From 3a26c8fe4bce8a3af62042dd0fca5f36221359a9 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Fri, 7 Jul 2023 17:21:22 +0200 Subject: Issue #62: Fixed wrong printf format specifiers. Changed cbits.h to use long long (guaranteed at least 64-bit) instead of int64_t for easier print. Second part of #62 is due to a clang compiler bug, can be avoided by using c_foreach instead of c_forpair. --- misc/examples/bits2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'misc/examples/bits2.c') diff --git a/misc/examples/bits2.c b/misc/examples/bits2.c index b002af3c..913bd185 100644 --- a/misc/examples/bits2.c +++ b/misc/examples/bits2.c @@ -9,10 +9,10 @@ int main() { 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)); -- cgit v1.2.3 From e9121702a5d69624ef1e782e85a8f032e4f4e875 Mon Sep 17 00:00:00 2001 From: tylov Date: Sat, 15 Jul 2023 23:20:16 +0200 Subject: Improved warning, and other enhancements in ccommon.h --- README.md | 2 +- docs/carc_api.md | 2 +- docs/cbox_api.md | 2 +- docs/ccommon_api.md | 10 +++++----- docs/cdeq_api.md | 2 +- docs/clist_api.md | 6 +++--- docs/cmap_api.md | 12 ++++++------ docs/cpque_api.md | 2 +- docs/cqueue_api.md | 2 +- docs/crandom_api.md | 2 +- docs/cregex_api.md | 2 +- docs/cset_api.md | 2 +- docs/csmap_api.md | 8 ++++---- docs/cspan_api.md | 6 +++--- docs/csset_api.md | 2 +- docs/cstack_api.md | 2 +- docs/cstr_api.md | 2 +- docs/csview_api.md | 6 +++--- docs/cvec_api.md | 4 ++-- include/c11/fmt.h | 2 +- include/stc/algo/crange.h | 2 +- include/stc/algo/filter.h | 2 +- include/stc/algo/sort.h | 4 ++-- include/stc/carc.h | 4 ++-- include/stc/cbits.h | 2 +- include/stc/cbox.h | 4 ++-- include/stc/ccommon.h | 6 +++--- include/stc/clist.h | 2 +- include/stc/crand.h | 2 +- include/stc/cvec.h | 2 +- misc/benchmarks/plotbench/cpque_benchmark.cpp | 2 +- misc/benchmarks/various/cspan_bench.c | 2 +- misc/benchmarks/various/rust_cmap.c | 2 +- misc/benchmarks/various/sso_bench.cpp | 2 +- misc/benchmarks/various/string_bench_STC.cpp | 2 +- misc/benchmarks/various/string_bench_STD.cpp | 2 +- misc/examples/arc_containers.c | 2 +- misc/examples/arc_demo.c | 2 +- misc/examples/arcvec_erase.c | 2 +- misc/examples/birthday.c | 2 +- misc/examples/bits2.c | 2 +- misc/examples/books.c | 2 +- misc/examples/box.c | 2 +- misc/examples/cointerleave.c | 2 +- misc/examples/complex.c | 2 +- misc/examples/convert.c | 2 +- misc/examples/csmap_erase.c | 2 +- misc/examples/csmap_find.c | 2 +- misc/examples/csmap_insert.c | 2 +- misc/examples/csset_erase.c | 2 +- misc/examples/cstr_match.c | 2 +- misc/examples/demos.c | 18 +++++++++--------- misc/examples/dining_philosophers.c | 2 +- misc/examples/forloops.c | 2 +- misc/examples/functor.c | 2 +- misc/examples/gauss2.c | 2 +- misc/examples/generator.c | 2 +- misc/examples/intrusive.c | 2 +- misc/examples/list.c | 2 +- misc/examples/list_erase.c | 2 +- misc/examples/list_splice.c | 2 +- misc/examples/lower_bound.c | 2 +- misc/examples/mmap.c | 2 +- misc/examples/multidim.c | 2 +- misc/examples/multimap.c | 2 +- misc/examples/music_arc.c | 4 ++-- misc/examples/new_list.c | 2 +- misc/examples/new_map.c | 2 +- misc/examples/new_pque.c | 2 +- misc/examples/new_queue.c | 2 +- misc/examples/new_smap.c | 2 +- misc/examples/new_vec.c | 2 +- misc/examples/person_arc.c | 2 +- misc/examples/printspan.c | 2 +- misc/examples/priority.c | 2 +- misc/examples/queue.c | 2 +- misc/examples/random.c | 2 +- misc/examples/rawptr_elements.c | 2 +- misc/examples/read.c | 2 +- misc/examples/regex2.c | 2 +- misc/examples/regex_match.c | 2 +- misc/examples/regex_replace.c | 2 +- misc/examples/replace.c | 2 +- misc/examples/scheduler.c | 2 +- misc/examples/sidebyside.cpp | 2 +- misc/examples/sorted_map.c | 2 +- misc/examples/splitstr.c | 2 +- misc/examples/sso_map.c | 2 +- misc/examples/sso_substr.c | 2 +- misc/examples/stack.c | 2 +- misc/examples/sview_split.c | 2 +- misc/examples/triples.c | 2 +- misc/examples/unordered_set.c | 2 +- misc/examples/utf8replace_c.c | 2 +- misc/examples/vikings.c | 2 +- 95 files changed, 128 insertions(+), 128 deletions(-) (limited to 'misc/examples/bits2.c') diff --git a/README.md b/README.md index 1601204d..b7e06790 100644 --- a/README.md +++ b/README.md @@ -181,7 +181,7 @@ Switching to a different container type, e.g. a sorted set (csset): #include // Use a sorted set instead #include -int main() +int main(void) { Floats nums = {0}; Floats_push(&nums, 30.f); diff --git a/docs/carc_api.md b/docs/carc_api.md index 254f868a..8b7b67a1 100644 --- a/docs/carc_api.md +++ b/docs/carc_api.md @@ -97,7 +97,7 @@ bool carc_X_value_eq(const i_key* x, const i_key* y); #define i_keyboxed Arc // Note: use i_keyboxed for carc or cbox value types #include -int main() +int main(void) { Stack s1 = {0}, s2 = {0}; Map *map; diff --git a/docs/cbox_api.md b/docs/cbox_api.md index 83d59521..b6c76d2f 100644 --- a/docs/cbox_api.md +++ b/docs/cbox_api.md @@ -90,7 +90,7 @@ void int_drop(int* x) { #define i_keyboxed IBox // NB: use i_keyboxed instead of i_key #include // IVec : std::vector> -int main() +int main(void) { IVec vec = c_init(Vec, {2021, 2012, 2022, 2015}); ISet set = {0}; diff --git a/docs/ccommon_api.md b/docs/ccommon_api.md index 6bce56af..e053f743 100644 --- a/docs/ccommon_api.md +++ b/docs/ccommon_api.md @@ -137,7 +137,7 @@ bool isPrime(long long i) { return true; } -int main() { +int main(void) { // Get 10 prime numbers starting from 1000. Skip the first 15 primes, // then select every 25th prime (including the initial). crange R = crange_make(1001, INT64_MAX, 2); // 1001, 1003, ... @@ -214,7 +214,7 @@ There is a [benchmark/test file here](../misc/benchmarks/various/csort_bench.c). #include #include -int main() { +int main(void) { int nums[] = {5, 3, 5, 9, 7, 4, 7, 2, 4, 9, 3, 1, 2, 6, 4}; intarray_sort_n(nums, c_arraylen(nums)); c_forrange (i, c_arraylen(arr)) printf(" %d", arr[i]); @@ -230,7 +230,7 @@ possible and very fast. Note that `i_more` must be defined to retain specified t #include #include -int main() { +int main(void) { MyDeq deq = c_init(MyDeq, {5, 3, 5, 9, 7, 4, 7, 2, 4, 9, 3, 1, 2, 6, 4}); MyDeq_sort_n(&deq, MyDeq_size(&deq)); c_foreach (i, MyDeq, deq) printf(" %d", *i.ref); @@ -348,7 +348,7 @@ int gcd(int a, int b) { // greatest common denominator return a; } -int main() +int main(void) { struct triples t = {.n=INT32_MAX}; int n = 0; @@ -500,7 +500,7 @@ cvec_str readFile(const char* name) return vec; } -int main() +int main(void) { c_with (cvec_str vec = readFile(__FILE__), cvec_str_drop(&vec)) c_foreach (i, cvec_str, vec) diff --git a/docs/cdeq_api.md b/docs/cdeq_api.md index 292b0933..c6de6cd6 100644 --- a/docs/cdeq_api.md +++ b/docs/cdeq_api.md @@ -101,7 +101,7 @@ void cdeq_X_value_drop(cdeq_X_value* pval); #include -int main() { +int main(void) { cdeq_i q = cdeq_i_init(); cdeq_i_push_front(&q, 10); c_foreach (i, cdeq_i, q) diff --git a/docs/clist_api.md b/docs/clist_api.md index 023cca41..3d785789 100644 --- a/docs/clist_api.md +++ b/docs/clist_api.md @@ -122,7 +122,7 @@ Interleave *push_front()* / *push_back()* then *sort()*: #include -int main() { +int main(void) { DList list = c_init(DList, {10., 20., 30., 40., 50., 60., 70., 80., 90.}); c_forrange (i, 1, 10) { @@ -159,7 +159,7 @@ Use of *erase_at()* and *erase_range()*: #include -int main () +int main(void) { clist_i L = c_init(clist_i, {10, 20, 30, 40, 50}); // 10 20 30 40 50 @@ -194,7 +194,7 @@ Splice `[30, 40]` from *L2* into *L1* before `3`: #include -int main() { +int main(void) { clist_i L1 = c_init(clist_i, {1, 2, 3, 4, 5}); clist_i L2 = c_init(clist_i, {10, 20, 30, 40, 50}); diff --git a/docs/cmap_api.md b/docs/cmap_api.md index 8ef322e6..eca350b4 100644 --- a/docs/cmap_api.md +++ b/docs/cmap_api.md @@ -121,7 +121,7 @@ bool c_memcmp_eq(const i_keyraw* a, const i_keyraw* b); // ! #define i_val_str #include -int main() +int main(void) { // Create an unordered_map of three strings (that map to strings) cmap_str umap = c_init(cmap_str, { @@ -165,7 +165,7 @@ This example uses a cmap with cstr as mapped value. #define i_val_str #include -int main() +int main(void) { uint32_t col = 0xcc7744ff; @@ -208,7 +208,7 @@ typedef struct { int x, y, z; } Vec3i; #define i_tag vi #include -int main() +int main(void) { // Define map with defered destruct cmap_vi vecs = {0}; @@ -243,7 +243,7 @@ typedef struct { int x, y, z; } Vec3i; #define i_tag iv #include -int main() +int main(void) { cmap_iv vecs = {0} @@ -304,7 +304,7 @@ static inline void Viking_drop(Viking* vk) { #define i_val int #include -int main() +int main(void) { // Use a HashMap to store the vikings' health points. Vikings vikings = {0}; @@ -380,7 +380,7 @@ static inline RViking Viking_toraw(const Viking* vp) { #define i_val int #include -int main() +int main(void) { Vikings vikings = {0}; diff --git a/docs/cpque_api.md b/docs/cpque_api.md index ca94e367..5b63dfd1 100644 --- a/docs/cpque_api.md +++ b/docs/cpque_api.md @@ -68,7 +68,7 @@ i_key cpque_X_value_clone(i_key value); #define i_tag i #include -int main() +int main(void) { intptr_t N = 10000000; crand_t rng = crand_init(1234); diff --git a/docs/cqueue_api.md b/docs/cqueue_api.md index bce62833..b324e5fc 100644 --- a/docs/cqueue_api.md +++ b/docs/cqueue_api.md @@ -74,7 +74,7 @@ void cqueue_X_value_drop(cqueue_X_value* pval); #include -int main() { +int main(void) { cqueue_i Q = cqueue_i_init(); // push() and pop() a few. diff --git a/docs/crandom_api.md b/docs/crandom_api.md index 74e23a6a..22a4f4dd 100644 --- a/docs/crandom_api.md +++ b/docs/crandom_api.md @@ -76,7 +76,7 @@ double crand_norm(crand_t* rng, crand_norm_t* dist); #define i_tag i #include -int main() +int main(void) { enum {N = 10000000}; const double Mean = -12.0, StdDev = 6.0, Scale = 74; diff --git a/docs/cregex_api.md b/docs/cregex_api.md index f87240f8..52476e09 100644 --- a/docs/cregex_api.md +++ b/docs/cregex_api.md @@ -102,7 +102,7 @@ If an error occurs ```cregex_compile``` returns a negative error code stored in #define i_import // include dependent cstr, utf8 and cregex function definitions. #include -int main() { +int main(void) { const char* input = "start date is 2023-03-01, end date 2025-12-31."; const char* pattern = "\\b(\\d\\d\\d\\d)-(\\d\\d)-(\\d\\d)\\b"; diff --git a/docs/cset_api.md b/docs/cset_api.md index 7bce3136..e894ad4f 100644 --- a/docs/cset_api.md +++ b/docs/cset_api.md @@ -83,7 +83,7 @@ cset_X_value cset_X_value_clone(cset_X_value val); #define i_key_str #include -int main () +int main(void) { Strset first, second={0}, third={0}, fourth={0}, fifth; diff --git a/docs/csmap_api.md b/docs/csmap_api.md index 2fd9f6a5..099d7dfc 100644 --- a/docs/csmap_api.md +++ b/docs/csmap_api.md @@ -108,7 +108,7 @@ void csmap_X_value_drop(csmap_X_value* pval); #define i_val_str // ditto #include -int main() +int main(void) { // Create a sorted map of three strings (maps to string) csmap_str colors = c_init(csmap_str, { @@ -166,7 +166,7 @@ static void print_result(strmap_result result) { print_node(result.ref); } -int main() +int main(void) { strmap m = {0}; @@ -191,7 +191,7 @@ This example uses a csmap with cstr as mapped value. #define i_val_str #include -int main() +int main(void) { uint32_t col = 0xcc7744ff; IDSMap idnames = c_init(IDSMap, { {100, "Red"}, {110, "Blue"} }); @@ -237,7 +237,7 @@ static int Vec3i_cmp(const Vec3i* a, const Vec3i* b) { #include #include -int main() +int main(void) { csmap_vi vmap = {0}; diff --git a/docs/cspan_api.md b/docs/cspan_api.md index 1089e48d..09821450 100644 --- a/docs/cspan_api.md +++ b/docs/cspan_api.md @@ -101,7 +101,7 @@ if __name__ == '__main__': #include using_cspan3(myspan, int); // define myspan, myspan2, myspan3. -int main() { +int main(void) { int arr[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24}; myspan3 ms3 = cspan_md(arr, 2, 3, 4); // C-order, i.e. row-major. @@ -123,7 +123,7 @@ int main() { #include #include -int main() { +int main(void) { int arr[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24}; std::mdspan ms3(arr, 2, 3, 4); @@ -147,7 +147,7 @@ Slicing cspan without and with reducing the rank: using_cspan3(Span, int); // Shorthand to define Span, Span2, and Span3 -int main() +int main(void) { // c_init() can create any STC container/span from an initializer list: Span span = c_init(Span, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, diff --git a/docs/csset_api.md b/docs/csset_api.md index d086b660..aef3af3c 100644 --- a/docs/csset_api.md +++ b/docs/csset_api.md @@ -83,7 +83,7 @@ csset_X_value csset_X_value_clone(csset_X_value val); #define i_key_str #include -int main () +int main(void) { SSet second={0}, third={0}, fourth={0}, fifth={0}; diff --git a/docs/cstack_api.md b/docs/cstack_api.md index 51889d7f..e799b152 100644 --- a/docs/cstack_api.md +++ b/docs/cstack_api.md @@ -77,7 +77,7 @@ void cstack_X_value_drop(cvec_X_value* pval); #include -int main() { +int main(void) { IStack stk = IStack_init(); for (int i=0; i < 100; ++i) diff --git a/docs/cstr_api.md b/docs/cstr_api.md index c7d19e0c..dae5669f 100644 --- a/docs/cstr_api.md +++ b/docs/cstr_api.md @@ -160,7 +160,7 @@ char* cstrnstrn(const char* str, const char* search, intptr_t slen, intpt #define i_implement #include -int main() { +int main(void) { cstr s0, s1, full_path; c_defer( cstr_drop(&s0), diff --git a/docs/csview_api.md b/docs/csview_api.md index 33df6a64..79a5c07b 100644 --- a/docs/csview_api.md +++ b/docs/csview_api.md @@ -121,7 +121,7 @@ uint64_t csview_hash(const csview* x); #include #include -int main () +int main(void) { cstr str1 = cstr_lit("We think in generalities, but we live in details."); // (quoting Alfred N. Whitehead) @@ -151,7 +151,7 @@ red Apples #define i_import // include dependent cstr, utf8 and cregex function definitions. #include -int main() +int main(void) { cstr s1 = cstr_lit("hell😀 w😀rld"); @@ -198,7 +198,7 @@ cstack_str string_split(csview input, const char* sep) return out; } -int main() +int main(void) { print_split(c_sv("//This is a//double-slash//separated//string"), "//"); print_split(c_sv("This has no matching separator"), "xx"); diff --git a/docs/cvec_api.md b/docs/cvec_api.md index ce85e446..d38ef23f 100644 --- a/docs/cvec_api.md +++ b/docs/cvec_api.md @@ -112,7 +112,7 @@ cvec_X_raw cvec_X_value_drop(cvec_X_value* pval); #include -int main() +int main(void) { // Create a vector containing integers cvec_int vec = {0}; @@ -153,7 +153,7 @@ sorted: 5 7 8 13 16 25 #define i_key_str #include -int main() { +int main(void) { cvec_str names = cvec_str_init(); cvec_str_emplace(&names, "Mary"); diff --git a/include/c11/fmt.h b/include/c11/fmt.h index 45044e33..d2eab8bc 100644 --- a/include/c11/fmt.h +++ b/include/c11/fmt.h @@ -33,7 +33,7 @@ void fmt_close(fmt_stream* ss); #define FMT_SHORTS #include "c11/fmt.h" -int main() { +int main(void) { const double pi = 3.141592653589793; const size_t x = 1234567890; const char* string = "Hello world"; diff --git a/include/stc/algo/crange.h b/include/stc/algo/crange.h index 45ef53a1..03162a2d 100644 --- a/include/stc/algo/crange.h +++ b/include/stc/algo/crange.h @@ -25,7 +25,7 @@ #include #include -int main() +int main(void) { crange r1 = crange_make(80, 90); c_foreach (i, crange, r1) diff --git a/include/stc/algo/filter.h b/include/stc/algo/filter.h index f5de1811..4a227927 100644 --- a/include/stc/algo/filter.h +++ b/include/stc/algo/filter.h @@ -26,7 +26,7 @@ #include #include -int main() +int main(void) { cstack_int stk = c_init(cstack_int, {1, 2, 3, 4, 5, 6, 7, 8, 9}); diff --git a/include/stc/algo/sort.h b/include/stc/algo/sort.h index 01e7d521..06d7395f 100644 --- a/include/stc/algo/sort.h +++ b/include/stc/algo/sort.h @@ -31,7 +31,7 @@ template params: #define i_key int #include -int main() { +int main(void) { int nums[] = {23, 321, 5434, 25, 245, 1, 654, 33, 543, 21}; intarray_sort_n(nums, c_arraylen(nums)); @@ -48,7 +48,7 @@ int main() { #include #include -int main() { +int main(void) { IDeq nums = c_init(IDeq, {5434, 25, 245, 1, 654, 33, 543, 21}); IDeq_push_front(&nums, 23); IDeq_push_front(&nums, 321); diff --git a/include/stc/carc.h b/include/stc/carc.h index b77b7dfb..9ba2ddd1 100644 --- a/include/stc/carc.h +++ b/include/stc/carc.h @@ -46,7 +46,7 @@ void Person_drop(Person* p) { #define i_opt c_no_cmp|c_no_hash // exclude cmp, hash #include -int main() { +int main(void) { ArcPers p = ArcPers_from(Person_make("John", "Smiths")); ArcPers q = ArcPers_clone(p); // share the pointer @@ -225,4 +225,4 @@ STC_INLINE void _cx_MEMB(_assign)(_cx_Self* self, _cx_Self ptr) { #undef _i_atomic_inc #undef _i_atomic_dec_and_test #include "priv/template2.h" -#undef _i_carc \ No newline at end of file +#undef _i_carc diff --git a/include/stc/cbits.h b/include/stc/cbits.h index 66bc6354..3b5785d3 100644 --- a/include/stc/cbits.h +++ b/include/stc/cbits.h @@ -26,7 +26,7 @@ Similar to boost::dynamic_bitset / std::bitset #include #include "cbits.h" -int main() { +int main(void) { cbits bset = cbits_with_size(23, true); cbits_reset(&bset, 9); cbits_resize(&bset, 43, false); diff --git a/include/stc/cbox.h b/include/stc/cbox.h index 86d5a6a6..25d41b92 100644 --- a/include/stc/cbox.h +++ b/include/stc/cbox.h @@ -47,7 +47,7 @@ void Person_drop(Person* p) { #define i_no_cmp // no cmp/hash is defined #include -int main() { +int main(void) { c_auto (PBox, p, q) { p = PBox_from(Person_from("John Smiths", "josmiths@gmail.com")); @@ -205,4 +205,4 @@ STC_INLINE void _cx_MEMB(_assign)(_cx_Self* self, _cx_Self* moved) { { return c_default_hash(&self->get); } #endif #include "priv/template2.h" -#undef _i_cbox \ No newline at end of file +#undef _i_cbox diff --git a/include/stc/ccommon.h b/include/stc/ccommon.h index 45c3a360..1f9ea80d 100644 --- a/include/stc/ccommon.h +++ b/include/stc/ccommon.h @@ -85,7 +85,7 @@ typedef long long _llong; #define c_assert(expr) assert(expr) #endif #define c_container_of(p, C, m) ((C*)((char*)(1 ? (p) : &((C*)0)->m) - offsetof(C, m))) -#define c_const_cast(T, p) ((T)(p) + 0*sizeof((T)0 == (p))) +#define c_const_cast(T, p) ((T)(1 ? (p) : (T)0)) #define c_swap(T, xp, yp) do { T *_xp = xp, *_yp = yp, \ _tv = *_xp; *_xp = *_yp; *_yp = _tv; } while (0) #define c_sizeof (intptr_t)sizeof @@ -96,8 +96,8 @@ typedef long long _llong; #define c_memmove(d, s, ilen) memmove(d, s, c_i2u(ilen)) #define c_memset(d, val, ilen) memset(d, val, c_i2u(ilen)) #define c_memcmp(a, b, ilen) memcmp(a, b, c_i2u(ilen)) -#define c_u2i(u) ((intptr_t)((u) + 0*sizeof((u) == 1U))) -#define c_i2u(i) ((size_t)(i) + 0*sizeof((i) == 1)) +#define c_u2i(u) ((intptr_t)(1 ? (u) : (size_t)1)) +#define c_i2u(i) ((size_t)(1 ? (i) : (intptr_t)1)) #define c_LTu(a, b) ((size_t)(a) < (size_t)(b)) // x and y are i_keyraw* type, defaults to i_key*: diff --git a/include/stc/clist.h b/include/stc/clist.h index 9cc1bb39..d7cf30b9 100644 --- a/include/stc/clist.h +++ b/include/stc/clist.h @@ -32,7 +32,7 @@ #define i_tag ix #include - int main() + int main(void) { c_auto (clist_ix, list) { diff --git a/include/stc/crand.h b/include/stc/crand.h index 89b681cd..0a6aa9e0 100644 --- a/include/stc/crand.h +++ b/include/stc/crand.h @@ -29,7 +29,7 @@ // crand: Pseudo-random number generator #include "stc/crand.h" -int main() { +int main(void) { uint64_t seed = 123456789; crand_t rng = crand_init(seed); crand_unif_t dist1 = crand_unif_init(1, 6); diff --git a/include/stc/cvec.h b/include/stc/cvec.h index 9b95306e..d08e382f 100644 --- a/include/stc/cvec.h +++ b/include/stc/cvec.h @@ -44,7 +44,7 @@ struct MyStruct { #define i_tag i32 #include -int main() { +int main(void) { cvec_i32 vec = {0}; cvec_i32_push(&vec, 123); cvec_i32_drop(&vec); diff --git a/misc/benchmarks/plotbench/cpque_benchmark.cpp b/misc/benchmarks/plotbench/cpque_benchmark.cpp index 2d4c7a28..6c62ae3e 100644 --- a/misc/benchmarks/plotbench/cpque_benchmark.cpp +++ b/misc/benchmarks/plotbench/cpque_benchmark.cpp @@ -58,7 +58,7 @@ void stc_test() } -int main() +int main(void) { puts("STD P.QUEUE:"); std_test(); diff --git a/misc/benchmarks/various/cspan_bench.c b/misc/benchmarks/various/cspan_bench.c index 392c9d3f..e3997ff0 100644 --- a/misc/benchmarks/various/cspan_bench.c +++ b/misc/benchmarks/various/cspan_bench.c @@ -114,7 +114,7 @@ static void MDRanges_loop_over_joined(intptr_t state) printf("joined: %.1f ms, %f\n", 1000.0f * t / CLOCKS_PER_SEC, sum); } -int main() +int main(void) { for (int i = 0; i < nx * ny * nz; ++i) Vin[i] = i + 1.23; diff --git a/misc/benchmarks/various/rust_cmap.c b/misc/benchmarks/various/rust_cmap.c index abdb42b0..97047e0b 100644 --- a/misc/benchmarks/various/rust_cmap.c +++ b/misc/benchmarks/various/rust_cmap.c @@ -22,7 +22,7 @@ uint64_t romu_trio(uint64_t s[3]) { return xp; } -int main() +int main(void) { cmap_u64 m = {0}; diff --git a/misc/benchmarks/various/sso_bench.cpp b/misc/benchmarks/various/sso_bench.cpp index 6d3d107a..244c1291 100644 --- a/misc/benchmarks/various/sso_bench.cpp +++ b/misc/benchmarks/various/sso_bench.cpp @@ -112,7 +112,7 @@ int benchmark_lookup(C& container, const int n, const int strsize) { } #include -int main() { +int main(void) { uint64_t seed = time(NULL); // 4321; int sum, n; diff --git a/misc/benchmarks/various/string_bench_STC.cpp b/misc/benchmarks/various/string_bench_STC.cpp index 319b0b19..a5dfd901 100644 --- a/misc/benchmarks/various/string_bench_STC.cpp +++ b/misc/benchmarks/various/string_bench_STC.cpp @@ -184,7 +184,7 @@ void benchmark( //const size_t MAX_LOOP = 1000000; const size_t MAX_LOOP = 2000; -int main() +int main(void) { c_auto (cvec_str, vec_string) c_auto (cvec_sv, vec_stringview) diff --git a/misc/benchmarks/various/string_bench_STD.cpp b/misc/benchmarks/various/string_bench_STD.cpp index 07934948..153ac02f 100644 --- a/misc/benchmarks/various/string_bench_STD.cpp +++ b/misc/benchmarks/various/string_bench_STD.cpp @@ -194,7 +194,7 @@ void benchmark( //const size_t MAX_LOOP = 1000000; const size_t MAX_LOOP = 2000; -int main() +int main(void) { std::vector vec_shortstr; std::vector vec_shortstrview; diff --git a/misc/examples/arc_containers.c b/misc/examples/arc_containers.c index 524758e7..2fb04c56 100644 --- a/misc/examples/arc_containers.c +++ b/misc/examples/arc_containers.c @@ -24,7 +24,7 @@ #define i_keyboxed Arc // as above #include -int main() +int main(void) { Stack stack = {0}; List list = {0}; diff --git a/misc/examples/arc_demo.c b/misc/examples/arc_demo.c index 547e1737..87d64e67 100644 --- a/misc/examples/arc_demo.c +++ b/misc/examples/arc_demo.c @@ -20,7 +20,7 @@ void int_drop(int* x) { #define i_keyboxed Arc // note: as above. #include // cvec_Arc (like: std::vector>) -int main() +int main(void) { const int years[] = {2021, 2012, 2022, 2015}; diff --git a/misc/examples/arcvec_erase.c b/misc/examples/arcvec_erase.c index f409258b..addef8b7 100644 --- a/misc/examples/arcvec_erase.c +++ b/misc/examples/arcvec_erase.c @@ -13,7 +13,7 @@ void show_drop(int* x) { printf("drop: %d\n", *x); } #include // Vec: cvec -int main() +int main(void) { Vec vec = c_init(Vec, {2012, 1990, 2012, 2019, 2015}); diff --git a/misc/examples/birthday.c b/misc/examples/birthday.c index 2820c42f..4742cb45 100644 --- a/misc/examples/birthday.c +++ b/misc/examples/birthday.c @@ -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/bits2.c b/misc/examples/bits2.c index 913bd185..de2f16f4 100644 --- a/misc/examples/bits2.c +++ b/misc/examples/bits2.c @@ -5,7 +5,7 @@ #define i_capacity 80 // enable fixed bitset on the stack #include -int main() +int main(void) { Bits s1 = Bits_from("1110100110111"); diff --git a/misc/examples/books.c b/misc/examples/books.c index 7f0660b8..1fd57f27 100644 --- a/misc/examples/books.c +++ b/misc/examples/books.c @@ -7,7 +7,7 @@ // Type inference lets us omit an explicit type signature (which // would be `HashMap` in this example). -int main() +int main(void) { cmap_str book_reviews = {0}; diff --git a/misc/examples/box.c b/misc/examples/box.c index 3f55e15d..94d126c0 100644 --- a/misc/examples/box.c +++ b/misc/examples/box.c @@ -36,7 +36,7 @@ void Person_drop(Person* p) { #define i_keyboxed PBox // "arcbox" informs that PBox is a smart pointer. #include -int main() +int main(void) { Persons vec = {0}; PBox p = PBox_from(Person_make("Laura", "Palmer")); diff --git a/misc/examples/cointerleave.c b/misc/examples/cointerleave.c index c3c5926a..599ceaab 100644 --- a/misc/examples/cointerleave.c +++ b/misc/examples/cointerleave.c @@ -56,7 +56,7 @@ void Use(void) c_drop(IVec, &a, &b); } -int main() +int main(void) { Use(); } diff --git a/misc/examples/complex.c b/misc/examples/complex.c index 405afef3..4eb1574b 100644 --- a/misc/examples/complex.c +++ b/misc/examples/complex.c @@ -28,7 +28,7 @@ #include -int main() +int main(void) { MapMap mmap = {0}; diff --git a/misc/examples/convert.c b/misc/examples/convert.c index 3f2f60f6..fa64560e 100644 --- a/misc/examples/convert.c +++ b/misc/examples/convert.c @@ -11,7 +11,7 @@ #define i_key_str #include -int main() +int main(void) { cmap_str map, mclone; cvec_str keys = {0}, values = {0}; diff --git a/misc/examples/csmap_erase.c b/misc/examples/csmap_erase.c index 9433d370..8d4eeae3 100644 --- a/misc/examples/csmap_erase.c +++ b/misc/examples/csmap_erase.c @@ -16,7 +16,7 @@ void printmap(mymap m) printf("\nsize() == %" c_ZI "\n\n", mymap_size(&m)); } -int main() +int main(void) { mymap m1 = {0}; diff --git a/misc/examples/csmap_find.c b/misc/examples/csmap_find.c index b535e9ad..c392338d 100644 --- a/misc/examples/csmap_find.c +++ b/misc/examples/csmap_find.c @@ -40,7 +40,7 @@ void findit(csmap_istr c, csmap_istr_key val) } } -int main() +int main(void) { csmap_istr m1 = c_init(csmap_istr, {{40, "Zr"}, {45, "Rh"}}); cvec_istr v = {0}; diff --git a/misc/examples/csmap_insert.c b/misc/examples/csmap_insert.c index df638c22..c9f02891 100644 --- a/misc/examples/csmap_insert.c +++ b/misc/examples/csmap_insert.c @@ -29,7 +29,7 @@ void print_istr(csmap_istr map) { puts(""); } -int main() +int main(void) { // insert single values csmap_ii m1 = {0}; diff --git a/misc/examples/csset_erase.c b/misc/examples/csset_erase.c index 649bb1e3..9c7f5e1a 100644 --- a/misc/examples/csset_erase.c +++ b/misc/examples/csset_erase.c @@ -3,7 +3,7 @@ #define i_key int #include -int main() +int main(void) { csset_int set = c_init(csset_int, {30, 20, 80, 40, 60, 90, 10, 70, 50}); diff --git a/misc/examples/cstr_match.c b/misc/examples/cstr_match.c index 10a843cf..be03e981 100644 --- a/misc/examples/cstr_match.c +++ b/misc/examples/cstr_match.c @@ -3,7 +3,7 @@ #include #include -int main() +int main(void) { cstr ss = cstr_lit("The quick brown fox jumps over the lazy dog.JPG"); diff --git a/misc/examples/demos.c b/misc/examples/demos.c index 2e91b20c..ecc89f2e 100644 --- a/misc/examples/demos.c +++ b/misc/examples/demos.c @@ -1,7 +1,7 @@ #define i_implement #include -void stringdemo1() +void stringdemo1(void) { cstr cs = cstr_lit("one-nine-three-seven-five"); printf("%s.\n", cstr_str(&cs)); @@ -32,7 +32,7 @@ void stringdemo1() #define i_tag ix #include -void vectordemo1() +void vectordemo1(void) { cvec_ix bignums = cvec_ix_with_capacity(100); cvec_ix_reserve(&bignums, 100); @@ -55,7 +55,7 @@ void vectordemo1() #define i_key_str #include -void vectordemo2() +void vectordemo2(void) { cvec_str names = {0}; cvec_str_emplace_back(&names, "Mary"); @@ -77,7 +77,7 @@ void vectordemo2() #define i_native_cmp #include -void listdemo1() +void listdemo1(void) { clist_ix nums = {0}, nums2 = {0}; for (int i = 0; i < 10; ++i) @@ -109,7 +109,7 @@ void listdemo1() #define i_tag i #include -void setdemo1() +void setdemo1(void) { cset_i nums = {0}; cset_i_insert(&nums, 8); @@ -125,7 +125,7 @@ void setdemo1() #define i_tag ii #include -void mapdemo1() +void mapdemo1(void) { cmap_ii nums = {0}; cmap_ii_insert(&nums, 8, 64); @@ -139,7 +139,7 @@ void mapdemo1() #define i_tag si #include -void mapdemo2() +void mapdemo2(void) { cmap_si nums = {0}; cmap_si_emplace_or_assign(&nums, "Hello", 64); @@ -161,7 +161,7 @@ void mapdemo2() #define i_val_str #include -void mapdemo3() +void mapdemo3(void) { cmap_str table = {0}; cmap_str_emplace(&table, "Map", "test"); @@ -181,7 +181,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/dining_philosophers.c b/misc/examples/dining_philosophers.c index 61fe67fb..a5063a42 100644 --- a/misc/examples/dining_philosophers.c +++ b/misc/examples/dining_philosophers.c @@ -86,7 +86,7 @@ int dining(struct Dining* d) return 0; } -int main() +int main(void) { struct Dining dine; cco_reset(&dine); diff --git a/misc/examples/forloops.c b/misc/examples/forloops.c index 99b12871..47cced8f 100644 --- a/misc/examples/forloops.c +++ b/misc/examples/forloops.c @@ -11,7 +11,7 @@ #include -int main() +int main(void) { puts("c_forrange:"); c_forrange (30) printf(" xx"); diff --git a/misc/examples/functor.c b/misc/examples/functor.c index ea409a56..e3bde1dd 100644 --- a/misc/examples/functor.c +++ b/misc/examples/functor.c @@ -30,7 +30,7 @@ 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"); diff --git a/misc/examples/gauss2.c b/misc/examples/gauss2.c index 67586181..1ab8ade5 100644 --- a/misc/examples/gauss2.c +++ b/misc/examples/gauss2.c @@ -10,7 +10,7 @@ #define i_val int #include -int main() +int main(void) { enum {N = 5000000}; uint64_t seed = (uint64_t)time(NULL); diff --git a/misc/examples/generator.c b/misc/examples/generator.c index 3ff7a645..a15f9ba5 100644 --- a/misc/examples/generator.c +++ b/misc/examples/generator.c @@ -42,7 +42,7 @@ Triple_iter Triple_begin(Triple* g) { } -int main() +int main(void) { puts("Pythagorean triples with c < 100:"); Triple triple = {.size=30}; // max number of triples diff --git a/misc/examples/intrusive.c b/misc/examples/intrusive.c index 1e3f7b83..4fca654b 100644 --- a/misc/examples/intrusive.c +++ b/misc/examples/intrusive.c @@ -14,7 +14,7 @@ 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})); diff --git a/misc/examples/list.c b/misc/examples/list.c index a0045db9..fa33305a 100644 --- a/misc/examples/list.c +++ b/misc/examples/list.c @@ -8,7 +8,7 @@ #define i_native_cmp #include -int main() { +int main(void) { const int n = 3000000; DList list = {0}; diff --git a/misc/examples/list_erase.c b/misc/examples/list_erase.c index 357dd75b..211c5a5d 100644 --- a/misc/examples/list_erase.c +++ b/misc/examples/list_erase.c @@ -5,7 +5,7 @@ #define i_key int #include -int main () +int main(void) { IList L = c_init(IList, {10, 20, 30, 40, 50}); diff --git a/misc/examples/list_splice.c b/misc/examples/list_splice.c index 25c2a42d..f1fd6e1f 100644 --- a/misc/examples/list_splice.c +++ b/misc/examples/list_splice.c @@ -13,7 +13,7 @@ void print_ilist(const char* s, clist_i list) puts(""); } -int main () +int main(void) { clist_i list1 = c_init(clist_i, {1, 2, 3, 4, 5}); clist_i list2 = c_init(clist_i, {10, 20, 30, 40, 50}); diff --git a/misc/examples/lower_bound.c b/misc/examples/lower_bound.c index ee32f49b..e5d816e9 100644 --- a/misc/examples/lower_bound.c +++ b/misc/examples/lower_bound.c @@ -7,7 +7,7 @@ #define i_key int #include -int main() +int main(void) { // TEST SORTED VECTOR { diff --git a/misc/examples/mmap.c b/misc/examples/mmap.c index fd00499c..04a605a7 100644 --- a/misc/examples/mmap.c +++ b/misc/examples/mmap.c @@ -30,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/multidim.c b/misc/examples/multidim.c index 45b97378..798a1126 100644 --- a/misc/examples/multidim.c +++ b/misc/examples/multidim.c @@ -6,7 +6,7 @@ using_cspan3(ispan, int); -int main() +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}); diff --git a/misc/examples/multimap.c b/misc/examples/multimap.c index a89b251b..1068a5dc 100644 --- a/misc/examples/multimap.c +++ b/misc/examples/multimap.c @@ -66,7 +66,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/music_arc.c b/misc/examples/music_arc.c index 49008523..16111b0b 100644 --- a/misc/examples/music_arc.c +++ b/misc/examples/music_arc.c @@ -31,7 +31,7 @@ void Song_drop(Song* s) { #define i_keyboxed SongArc // use i_keyboxed on carc / cbox (instead of i_key) #include -void example3() +void example3(void) { SongVec vec1 = c_init(SongVec, { Song_make("Bob Dylan", "The Times They Are A Changing"), @@ -61,7 +61,7 @@ void example3() c_drop(SongVec, &vec1, &vec2); } -int main() +int main(void) { example3(); } diff --git a/misc/examples/new_list.c b/misc/examples/new_list.c index ee250b2b..9676e7b4 100644 --- a/misc/examples/new_list.c +++ b/misc/examples/new_list.c @@ -43,7 +43,7 @@ void MyStruct_drop(MyStruct* s) { } -int main() +int main(void) { MyStruct my = {0}; clist_i32_push_back(&my.intlist, 123); diff --git a/misc/examples/new_map.c b/misc/examples/new_map.c index 277bcbc2..de990040 100644 --- a/misc/examples/new_map.c +++ b/misc/examples/new_map.c @@ -41,7 +41,7 @@ int point_cmp(const Point* a, const Point* b) { #include -int main() +int main(void) { cmap_pnt pmap = c_init(cmap_pnt, {{{42, 14}, 1}, {{32, 94}, 2}, {{62, 81}, 3}}); diff --git a/misc/examples/new_pque.c b/misc/examples/new_pque.c index 3df39e0e..16823bb6 100644 --- a/misc/examples/new_pque.c +++ b/misc/examples/new_pque.c @@ -8,7 +8,7 @@ typedef struct Point { int x, y; } Point; #include -int main() +int main(void) { PointQ pque = c_init(PointQ, {{23, 80}, {12, 32}, {54, 74}, {12, 62}}); // print diff --git a/misc/examples/new_queue.c b/misc/examples/new_queue.c index 104871bf..f3592df6 100644 --- a/misc/examples/new_queue.c +++ b/misc/examples/new_queue.c @@ -20,7 +20,7 @@ int point_cmp(const Point* a, const Point* b) { #define i_key int #include -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); diff --git a/misc/examples/new_smap.c b/misc/examples/new_smap.c index 77c4cdce..ee946c9a 100644 --- a/misc/examples/new_smap.c +++ b/misc/examples/new_smap.c @@ -36,7 +36,7 @@ int point_cmp(const Point* a, const Point* b) { #include -int main() +int main(void) { PMap pmap = c_init(PMap, { {{42, 14}, 1}, diff --git a/misc/examples/new_vec.c b/misc/examples/new_vec.c index 6d928cfc..88efd55a 100644 --- a/misc/examples/new_vec.c +++ b/misc/examples/new_vec.c @@ -23,7 +23,7 @@ typedef struct Point { int x, y; } Point; #define i_is_forward #include -int main() +int main(void) { MyStruct my = {0}; diff --git a/misc/examples/person_arc.c b/misc/examples/person_arc.c index 3a759610..38c883a7 100644 --- a/misc/examples/person_arc.c +++ b/misc/examples/person_arc.c @@ -39,7 +39,7 @@ void Person_drop(Person* p) { #include -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/printspan.c b/misc/examples/printspan.c index 5084536a..cd3c5f4f 100644 --- a/misc/examples/printspan.c +++ b/misc/examples/printspan.c @@ -20,7 +20,7 @@ void printMe(intspan container) { puts(""); } -int main() +int main(void) { intspan sp1 = cspan_init(intspan, {1, 2}); printMe( sp1 ); diff --git a/misc/examples/priority.c b/misc/examples/priority.c index 148e8fc5..bf2e188a 100644 --- a/misc/examples/priority.c +++ b/misc/examples/priority.c @@ -8,7 +8,7 @@ #define i_tag i #include -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); diff --git a/misc/examples/queue.c b/misc/examples/queue.c index 3154f115..56b5beb9 100644 --- a/misc/examples/queue.c +++ b/misc/examples/queue.c @@ -5,7 +5,7 @@ #define i_tag i #include -int main() { +int main(void) { int n = 100000000; crand_unif_t dist; crand_t rng = crand_init(1234); diff --git a/misc/examples/random.c b/misc/examples/random.c index e783fe55..b7c0f277 100644 --- a/misc/examples/random.c +++ b/misc/examples/random.c @@ -2,7 +2,7 @@ #include #include -int main() +int main(void) { const int N = 1000000000; const uint64_t seed = (uint64_t)time(NULL), range = 1000000; diff --git a/misc/examples/rawptr_elements.c b/misc/examples/rawptr_elements.c index 9c394d8e..694ce12e 100644 --- a/misc/examples/rawptr_elements.c +++ b/misc/examples/rawptr_elements.c @@ -25,7 +25,7 @@ #define i_valboxed IBox // i_valboxed: use properties from IBox automatically #include -int main() +int main(void) { // These have the same behaviour, except IBox has a get member: SIPtrMap map1 = {0}; diff --git a/misc/examples/read.c b/misc/examples/read.c index c25cd740..b12f7409 100644 --- a/misc/examples/read.c +++ b/misc/examples/read.c @@ -15,7 +15,7 @@ cvec_str read_file(const char* name) 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/regex2.c b/misc/examples/regex2.c index 734190cb..a798b1a1 100644 --- a/misc/examples/regex2.c +++ b/misc/examples/regex2.c @@ -1,7 +1,7 @@ #define i_import #include -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])", diff --git a/misc/examples/regex_match.c b/misc/examples/regex_match.c index 88d3747b..11426d2d 100644 --- a/misc/examples/regex_match.c +++ b/misc/examples/regex_match.c @@ -6,7 +6,7 @@ #define i_key float #include -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." diff --git a/misc/examples/regex_replace.c b/misc/examples/regex_replace.c index 76664b1b..f1ea2711 100644 --- a/misc/examples/regex_replace.c +++ b/misc/examples/regex_replace.c @@ -12,7 +12,7 @@ bool add_10_years(int i, csview match, cstr* out) { 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"; diff --git a/misc/examples/replace.c b/misc/examples/replace.c index 9ac26c07..59a56bf7 100644 --- a/misc/examples/replace.c +++ b/misc/examples/replace.c @@ -1,7 +1,7 @@ #define i_implement #include -int main () +int main(void) { const char *base = "this is a test string."; const char *s2 = "n example"; diff --git a/misc/examples/scheduler.c b/misc/examples/scheduler.c index d812ff42..38defd0f 100644 --- a/misc/examples/scheduler.c +++ b/misc/examples/scheduler.c @@ -68,7 +68,7 @@ void Use(void) Scheduler_drop(&scheduler); } -int main() +int main(void) { Use(); } diff --git a/misc/examples/sidebyside.cpp b/misc/examples/sidebyside.cpp index a7c1008c..9414b691 100644 --- a/misc/examples/sidebyside.cpp +++ b/misc/examples/sidebyside.cpp @@ -13,7 +13,7 @@ #define i_val int #include -int main() { +int main(void) { { std::map hist; hist.emplace(12, 100).first->second += 1; diff --git a/misc/examples/sorted_map.c b/misc/examples/sorted_map.c index ff727632..89381554 100644 --- a/misc/examples/sorted_map.c +++ b/misc/examples/sorted_map.c @@ -5,7 +5,7 @@ #define i_val int #include -int main() +int main(void) { // empty map containers diff --git a/misc/examples/splitstr.c b/misc/examples/splitstr.c index 32b5f17f..ef7ed174 100644 --- a/misc/examples/splitstr.c +++ b/misc/examples/splitstr.c @@ -4,7 +4,7 @@ #define i_implement #include -int main() +int main(void) { puts("Split with c_fortoken (csview):"); diff --git a/misc/examples/sso_map.c b/misc/examples/sso_map.c index b78dcb2e..4f84b651 100644 --- a/misc/examples/sso_map.c +++ b/misc/examples/sso_map.c @@ -4,7 +4,7 @@ #define i_val_str #include -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/sso_substr.c index 9b062eed..687658df 100644 --- a/misc/examples/sso_substr.c +++ b/misc/examples/sso_substr.c @@ -3,7 +3,7 @@ #define i_implement #include -int main () +int main(void) { cstr str = cstr_lit("We think in generalities, but we live in details."); csview sv1 = cstr_substr_ex(&str, 3, 5); // "think" diff --git a/misc/examples/stack.c b/misc/examples/stack.c index 96bab24b..6297fb6f 100644 --- a/misc/examples/stack.c +++ b/misc/examples/stack.c @@ -10,7 +10,7 @@ #define i_key char #include -int main() { +int main(void) { cstack_i stack = {0}; cstack_c chars = {0}; diff --git a/misc/examples/sview_split.c b/misc/examples/sview_split.c index 782e4096..ac275da0 100644 --- a/misc/examples/sview_split.c +++ b/misc/examples/sview_split.c @@ -3,7 +3,7 @@ #define i_implement #include -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/triples.c b/misc/examples/triples.c index a8ca6b47..9f2fcc1e 100644 --- a/misc/examples/triples.c +++ b/misc/examples/triples.c @@ -52,7 +52,7 @@ int triples_coro(struct triples* t) { return 0; } -int main() +int main(void) { puts("Vanilla triples:"); triples_vanilla(5); diff --git a/misc/examples/unordered_set.c b/misc/examples/unordered_set.c index 14d69ce5..dd899d78 100644 --- a/misc/examples/unordered_set.c +++ b/misc/examples/unordered_set.c @@ -5,7 +5,7 @@ #define i_key_str #include -int main() +int main(void) { // declaring set for storing string data-type cset_str stringSet = {0}; diff --git a/misc/examples/utf8replace_c.c b/misc/examples/utf8replace_c.c index 17352fee..1d54486f 100644 --- a/misc/examples/utf8replace_c.c +++ b/misc/examples/utf8replace_c.c @@ -1,7 +1,7 @@ #define i_implement #include -int main() +int main(void) { cstr hello = cstr_lit("hell😀 w😀rld"); printf("%s\n", cstr_str(&hello)); diff --git a/misc/examples/vikings.c b/misc/examples/vikings.c index d9024052..d6125854 100644 --- a/misc/examples/vikings.c +++ b/misc/examples/vikings.c @@ -41,7 +41,7 @@ static inline RViking Viking_toraw(const Viking* vp) { #define i_val int // mapped type #include -int main() +int main(void) { Vikings vikings = {0}; Vikings_emplace(&vikings, c_LITERAL(RViking){"Einar", "Norway"}, 20); -- cgit v1.2.3 From 900295256d825fc323149cd223c49787f32a3696 Mon Sep 17 00:00:00 2001 From: tylov Date: Thu, 20 Jul 2023 15:09:10 +0200 Subject: Moved examples to sub-directories. Added cotask1.c cotask2.c examples. --- misc/examples/algorithms/forfilter.c | 149 +++++++++++++++++ misc/examples/algorithms/forloops.c | 69 ++++++++ misc/examples/algorithms/random.c | 45 ++++++ misc/examples/algorithms/shape.c | 158 ++++++++++++++++++ misc/examples/algorithms/shape.cpp | 122 ++++++++++++++ misc/examples/arc_containers.c | 81 ---------- misc/examples/arc_demo.c | 62 -------- misc/examples/arcvec_erase.c | 50 ------ misc/examples/astar.c | 174 -------------------- misc/examples/birthday.c | 68 -------- misc/examples/bits.c | 66 -------- misc/examples/bits2.c | 41 ----- misc/examples/bitsets/bits.c | 66 ++++++++ misc/examples/bitsets/bits2.c | 41 +++++ misc/examples/bitsets/prime.c | 56 +++++++ misc/examples/books.c | 62 -------- misc/examples/box.c | 69 -------- misc/examples/box2.c | 82 ---------- misc/examples/cointerleave.c | 62 -------- misc/examples/complex.c | 49 ------ misc/examples/convert.c | 57 ------- misc/examples/coread.c | 41 ----- misc/examples/coroutines.c | 112 ------------- misc/examples/coroutines/cointerleave.c | 62 ++++++++ misc/examples/coroutines/coread.c | 41 +++++ misc/examples/coroutines/coroutines.c | 112 +++++++++++++ misc/examples/coroutines/cotasks1.c | 100 ++++++++++++ misc/examples/coroutines/cotasks2.c | 103 ++++++++++++ misc/examples/coroutines/dining_philosophers.c | 105 ++++++++++++ misc/examples/coroutines/generator.c | 55 +++++++ misc/examples/coroutines/scheduler.c | 74 +++++++++ misc/examples/coroutines/triples.c | 72 +++++++++ misc/examples/csmap_erase.c | 82 ---------- misc/examples/csmap_find.c | 73 --------- misc/examples/csmap_insert.c | 108 ------------- misc/examples/csset_erase.c | 41 ----- misc/examples/cstr_match.c | 26 --- misc/examples/demos.c | 194 ----------------------- misc/examples/dining_philosophers.c | 105 ------------ misc/examples/forfilter.c | 149 ----------------- misc/examples/forloops.c | 69 -------- misc/examples/functor.c | 57 ------- misc/examples/gauss2.c | 45 ------ misc/examples/generator.c | 55 ------- misc/examples/hashmap.c | 50 ------ misc/examples/hashmaps/birthday.c | 68 ++++++++ misc/examples/hashmaps/books.c | 62 ++++++++ misc/examples/hashmaps/hashmap.c | 50 ++++++ misc/examples/hashmaps/new_map.c | 75 +++++++++ misc/examples/hashmaps/phonebook.c | 72 +++++++++ misc/examples/hashmaps/unordered_set.c | 45 ++++++ misc/examples/hashmaps/vikings.c | 59 +++++++ misc/examples/inits.c | 108 ------------- misc/examples/intrusive.c | 33 ---- misc/examples/linkedlists/intrusive.c | 33 ++++ misc/examples/linkedlists/list.c | 64 ++++++++ misc/examples/linkedlists/list_erase.c | 30 ++++ misc/examples/linkedlists/list_splice.c | 38 +++++ misc/examples/linkedlists/new_list.c | 70 ++++++++ misc/examples/list.c | 64 -------- misc/examples/list_erase.c | 30 ---- misc/examples/list_splice.c | 38 ----- misc/examples/lower_bound.c | 66 -------- misc/examples/make.sh | 18 ++- misc/examples/mapmap.c | 64 -------- misc/examples/mixed/astar.c | 174 ++++++++++++++++++++ misc/examples/mixed/complex.c | 49 ++++++ misc/examples/mixed/convert.c | 57 +++++++ misc/examples/mixed/demos.c | 194 +++++++++++++++++++++++ misc/examples/mixed/inits.c | 108 +++++++++++++ misc/examples/mixed/read.c | 27 ++++ misc/examples/mmap.c | 65 -------- misc/examples/multidim.c | 67 -------- misc/examples/multimap.c | 102 ------------ misc/examples/music_arc.c | 67 -------- misc/examples/new_list.c | 70 -------- misc/examples/new_map.c | 75 --------- misc/examples/new_pque.c | 22 --- misc/examples/new_queue.c | 47 ------ misc/examples/new_smap.c | 67 -------- misc/examples/new_sptr.c | 75 --------- misc/examples/new_vec.c | 43 ----- misc/examples/person_arc.c | 77 --------- misc/examples/phonebook.c | 72 --------- misc/examples/prime.c | 56 ------- misc/examples/printspan.c | 52 ------ misc/examples/priority.c | 37 ----- misc/examples/priorityqueues/functor.c | 57 +++++++ misc/examples/priorityqueues/new_pque.c | 22 +++ misc/examples/priorityqueues/priority.c | 37 +++++ misc/examples/queue.c | 32 ---- misc/examples/queues/new_queue.c | 47 ++++++ misc/examples/queues/queue.c | 32 ++++ misc/examples/random.c | 45 ------ misc/examples/rawptr_elements.c | 59 ------- misc/examples/read.c | 27 ---- misc/examples/regex1.c | 32 ---- misc/examples/regex2.c | 34 ---- misc/examples/regex_match.c | 37 ----- misc/examples/regex_replace.c | 57 ------- misc/examples/regularexpressions/regex1.c | 32 ++++ misc/examples/regularexpressions/regex2.c | 34 ++++ misc/examples/regularexpressions/regex_match.c | 37 +++++ misc/examples/regularexpressions/regex_replace.c | 57 +++++++ misc/examples/replace.c | 36 ----- misc/examples/scheduler.c | 74 --------- misc/examples/shape.c | 158 ------------------ misc/examples/shape.cpp | 122 -------------- misc/examples/sidebyside.cpp | 57 ------- misc/examples/smartpointers/arc_containers.c | 81 ++++++++++ misc/examples/smartpointers/arc_demo.c | 62 ++++++++ misc/examples/smartpointers/arcvec_erase.c | 50 ++++++ misc/examples/smartpointers/box.c | 69 ++++++++ misc/examples/smartpointers/box2.c | 82 ++++++++++ misc/examples/smartpointers/music_arc.c | 67 ++++++++ misc/examples/smartpointers/new_sptr.c | 75 +++++++++ misc/examples/smartpointers/person_arc.c | 77 +++++++++ misc/examples/smartpointers/rawptr_elements.c | 59 +++++++ misc/examples/sorted_map.c | 67 -------- misc/examples/sortedmaps/csmap_erase.c | 82 ++++++++++ misc/examples/sortedmaps/csmap_find.c | 73 +++++++++ misc/examples/sortedmaps/csmap_insert.c | 108 +++++++++++++ misc/examples/sortedmaps/csset_erase.c | 41 +++++ misc/examples/sortedmaps/gauss2.c | 45 ++++++ misc/examples/sortedmaps/listmap.c | 65 ++++++++ misc/examples/sortedmaps/mapmap.c | 64 ++++++++ misc/examples/sortedmaps/multimap.c | 102 ++++++++++++ misc/examples/sortedmaps/new_smap.c | 67 ++++++++ misc/examples/sortedmaps/sorted_map.c | 67 ++++++++ misc/examples/spans/multidim.c | 67 ++++++++ misc/examples/spans/printspan.c | 52 ++++++ misc/examples/splitstr.c | 21 --- misc/examples/sso_map.c | 19 --- misc/examples/sso_substr.c | 21 --- misc/examples/stack.c | 32 ---- misc/examples/strings/cstr_match.c | 26 +++ misc/examples/strings/replace.c | 36 +++++ misc/examples/strings/splitstr.c | 21 +++ misc/examples/strings/sso_map.c | 19 +++ misc/examples/strings/sso_substr.c | 21 +++ misc/examples/strings/sview_split.c | 20 +++ misc/examples/strings/utf8replace_c.c | 25 +++ misc/examples/strings/utf8replace_rs.rs | 22 +++ misc/examples/sview_split.c | 20 --- misc/examples/triples.c | 72 --------- misc/examples/unordered_set.c | 45 ------ misc/examples/utf8replace_c.c | 25 --- misc/examples/utf8replace_rs.rs | 22 --- misc/examples/vectors/lower_bound.c | 66 ++++++++ misc/examples/vectors/new_vec.c | 43 +++++ misc/examples/vectors/stack.c | 32 ++++ misc/examples/vikings.c | 59 ------- 152 files changed, 4856 insertions(+), 4708 deletions(-) create mode 100644 misc/examples/algorithms/forfilter.c create mode 100644 misc/examples/algorithms/forloops.c create mode 100644 misc/examples/algorithms/random.c create mode 100644 misc/examples/algorithms/shape.c create mode 100644 misc/examples/algorithms/shape.cpp delete mode 100644 misc/examples/arc_containers.c delete mode 100644 misc/examples/arc_demo.c delete mode 100644 misc/examples/arcvec_erase.c delete mode 100644 misc/examples/astar.c delete mode 100644 misc/examples/birthday.c delete mode 100644 misc/examples/bits.c delete mode 100644 misc/examples/bits2.c create mode 100644 misc/examples/bitsets/bits.c create mode 100644 misc/examples/bitsets/bits2.c create mode 100644 misc/examples/bitsets/prime.c delete mode 100644 misc/examples/books.c delete mode 100644 misc/examples/box.c delete mode 100644 misc/examples/box2.c delete mode 100644 misc/examples/cointerleave.c delete mode 100644 misc/examples/complex.c delete mode 100644 misc/examples/convert.c delete mode 100644 misc/examples/coread.c delete mode 100644 misc/examples/coroutines.c create mode 100644 misc/examples/coroutines/cointerleave.c create mode 100644 misc/examples/coroutines/coread.c create mode 100644 misc/examples/coroutines/coroutines.c create mode 100644 misc/examples/coroutines/cotasks1.c create mode 100644 misc/examples/coroutines/cotasks2.c create mode 100644 misc/examples/coroutines/dining_philosophers.c create mode 100644 misc/examples/coroutines/generator.c create mode 100644 misc/examples/coroutines/scheduler.c create mode 100644 misc/examples/coroutines/triples.c delete mode 100644 misc/examples/csmap_erase.c delete mode 100644 misc/examples/csmap_find.c delete mode 100644 misc/examples/csmap_insert.c delete mode 100644 misc/examples/csset_erase.c delete mode 100644 misc/examples/cstr_match.c delete mode 100644 misc/examples/demos.c delete mode 100644 misc/examples/dining_philosophers.c delete mode 100644 misc/examples/forfilter.c delete mode 100644 misc/examples/forloops.c delete mode 100644 misc/examples/functor.c delete mode 100644 misc/examples/gauss2.c delete mode 100644 misc/examples/generator.c delete mode 100644 misc/examples/hashmap.c create mode 100644 misc/examples/hashmaps/birthday.c create mode 100644 misc/examples/hashmaps/books.c create mode 100644 misc/examples/hashmaps/hashmap.c create mode 100644 misc/examples/hashmaps/new_map.c create mode 100644 misc/examples/hashmaps/phonebook.c create mode 100644 misc/examples/hashmaps/unordered_set.c create mode 100644 misc/examples/hashmaps/vikings.c delete mode 100644 misc/examples/inits.c delete mode 100644 misc/examples/intrusive.c create mode 100644 misc/examples/linkedlists/intrusive.c create mode 100644 misc/examples/linkedlists/list.c create mode 100644 misc/examples/linkedlists/list_erase.c create mode 100644 misc/examples/linkedlists/list_splice.c create mode 100644 misc/examples/linkedlists/new_list.c delete mode 100644 misc/examples/list.c delete mode 100644 misc/examples/list_erase.c delete mode 100644 misc/examples/list_splice.c delete mode 100644 misc/examples/lower_bound.c delete mode 100644 misc/examples/mapmap.c create mode 100644 misc/examples/mixed/astar.c create mode 100644 misc/examples/mixed/complex.c create mode 100644 misc/examples/mixed/convert.c create mode 100644 misc/examples/mixed/demos.c create mode 100644 misc/examples/mixed/inits.c create mode 100644 misc/examples/mixed/read.c delete mode 100644 misc/examples/mmap.c delete mode 100644 misc/examples/multidim.c delete mode 100644 misc/examples/multimap.c delete mode 100644 misc/examples/music_arc.c delete mode 100644 misc/examples/new_list.c delete mode 100644 misc/examples/new_map.c delete mode 100644 misc/examples/new_pque.c delete mode 100644 misc/examples/new_queue.c delete mode 100644 misc/examples/new_smap.c delete mode 100644 misc/examples/new_sptr.c delete mode 100644 misc/examples/new_vec.c delete mode 100644 misc/examples/person_arc.c delete mode 100644 misc/examples/phonebook.c delete mode 100644 misc/examples/prime.c delete mode 100644 misc/examples/printspan.c delete mode 100644 misc/examples/priority.c create mode 100644 misc/examples/priorityqueues/functor.c create mode 100644 misc/examples/priorityqueues/new_pque.c create mode 100644 misc/examples/priorityqueues/priority.c delete mode 100644 misc/examples/queue.c create mode 100644 misc/examples/queues/new_queue.c create mode 100644 misc/examples/queues/queue.c delete mode 100644 misc/examples/random.c delete mode 100644 misc/examples/rawptr_elements.c delete mode 100644 misc/examples/read.c delete mode 100644 misc/examples/regex1.c delete mode 100644 misc/examples/regex2.c delete mode 100644 misc/examples/regex_match.c delete mode 100644 misc/examples/regex_replace.c create mode 100644 misc/examples/regularexpressions/regex1.c create mode 100644 misc/examples/regularexpressions/regex2.c create mode 100644 misc/examples/regularexpressions/regex_match.c create mode 100644 misc/examples/regularexpressions/regex_replace.c delete mode 100644 misc/examples/replace.c delete mode 100644 misc/examples/scheduler.c delete mode 100644 misc/examples/shape.c delete mode 100644 misc/examples/shape.cpp delete mode 100644 misc/examples/sidebyside.cpp create mode 100644 misc/examples/smartpointers/arc_containers.c create mode 100644 misc/examples/smartpointers/arc_demo.c create mode 100644 misc/examples/smartpointers/arcvec_erase.c create mode 100644 misc/examples/smartpointers/box.c create mode 100644 misc/examples/smartpointers/box2.c create mode 100644 misc/examples/smartpointers/music_arc.c create mode 100644 misc/examples/smartpointers/new_sptr.c create mode 100644 misc/examples/smartpointers/person_arc.c create mode 100644 misc/examples/smartpointers/rawptr_elements.c delete mode 100644 misc/examples/sorted_map.c create mode 100644 misc/examples/sortedmaps/csmap_erase.c create mode 100644 misc/examples/sortedmaps/csmap_find.c create mode 100644 misc/examples/sortedmaps/csmap_insert.c create mode 100644 misc/examples/sortedmaps/csset_erase.c create mode 100644 misc/examples/sortedmaps/gauss2.c create mode 100644 misc/examples/sortedmaps/listmap.c create mode 100644 misc/examples/sortedmaps/mapmap.c create mode 100644 misc/examples/sortedmaps/multimap.c create mode 100644 misc/examples/sortedmaps/new_smap.c create mode 100644 misc/examples/sortedmaps/sorted_map.c create mode 100644 misc/examples/spans/multidim.c create mode 100644 misc/examples/spans/printspan.c delete mode 100644 misc/examples/splitstr.c delete mode 100644 misc/examples/sso_map.c delete mode 100644 misc/examples/sso_substr.c delete mode 100644 misc/examples/stack.c create mode 100644 misc/examples/strings/cstr_match.c create mode 100644 misc/examples/strings/replace.c create mode 100644 misc/examples/strings/splitstr.c create mode 100644 misc/examples/strings/sso_map.c create mode 100644 misc/examples/strings/sso_substr.c create mode 100644 misc/examples/strings/sview_split.c create mode 100644 misc/examples/strings/utf8replace_c.c create mode 100644 misc/examples/strings/utf8replace_rs.rs delete mode 100644 misc/examples/sview_split.c delete mode 100644 misc/examples/triples.c delete mode 100644 misc/examples/unordered_set.c delete mode 100644 misc/examples/utf8replace_c.c delete mode 100644 misc/examples/utf8replace_rs.rs create mode 100644 misc/examples/vectors/lower_bound.c create mode 100644 misc/examples/vectors/new_vec.c create mode 100644 misc/examples/vectors/stack.c delete mode 100644 misc/examples/vikings.c (limited to 'misc/examples/bits2.c') diff --git a/misc/examples/algorithms/forfilter.c b/misc/examples/algorithms/forfilter.c new file mode 100644 index 00000000..f3c008b3 --- /dev/null +++ b/misc/examples/algorithms/forfilter.c @@ -0,0 +1,149 @@ +#include +#define i_import +#include +#define i_implement +#include +#include +#include + +#define i_type IVec +#define i_key int +#include + +// filters and transforms: +#define flt_skipValue(i, x) (*i.ref != (x)) +#define flt_isEven(i) ((*i.ref & 1) == 0) +#define flt_isOdd(i) (*i.ref & 1) +#define flt_square(i) (*i.ref * *i.ref) + +void demo1(void) +{ + 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)) + printf(" %d", *i.ref); + puts(""); + + int sum = 0; + c_forfilter (i, IVec, vec, + c_flt_skipwhile(i, *i.ref != 80) && + c_flt_skip(i, 1) && + flt_isEven(i) && + flt_skipValue(i, 80) && + c_flt_take(i, 5) // short-circuit + ){ + sum += flt_square(i); + } + + printf("\n sum: %d\n", sum); + IVec_drop(&vec); +} + + +/* Rust: +fn main() { + let vector = (1..) // Infinite range of integers + .skip_while(|x| *x != 11) // Skip initial numbers unequal 11 + .filter(|x| x % 2 != 0) // Collect odd numbers + .take(5) // Only take five numbers + .map(|x| x * x) // Square each number + .collect::>(); // Return as a new Vec + println!("{:?}", vector); // Print result +} +*/ +void demo2(void) +{ + IVec vector = {0}; + crange r = crange_make(INT64_MAX); + c_forfilter (x, crange, r, + c_flt_skipwhile(x, *x.ref != 11) && + (*x.ref % 2) != 0 && + c_flt_take(x, 5) + ){ + IVec_push(&vector, (int)(*x.ref * *x.ref)); + } + c_foreach (x, IVec, vector) printf(" %d", *x.ref); + + puts(""); + IVec_drop(&vector); +} + +/* Rust: +fn main() { + let sentence = "This is a sentence in Rust."; + let words: Vec<&str> = sentence + .split_whitespace() + .collect(); + let words_containing_i: Vec<&str> = words + .into_iter() + .filter(|word| word.contains("i")) + .collect(); + println!("{:?}", words_containing_i); +} +*/ +#define i_type SVec +#define i_keyclass csview +#include + +void demo3(void) +{ + const char* sentence = "This is a sentence in C99."; + SVec words = {0}; + c_fortoken (w, sentence, " ") // split words + SVec_push(&words, *w.ref); + + SVec words_containing_i = {0}; + c_forfilter (w, SVec, words, + csview_contains(*w.ref, "i")) + SVec_push(&words_containing_i, *w.ref); + + c_foreach (w, SVec, words_containing_i) + printf(" %.*s", c_SV(*w.ref)); + + puts(""); + c_drop(SVec, &words, &words_containing_i); +} + +void demo4(void) +{ + // Keep only uppercase letters and convert them to lowercase: + csview s = c_sv("ab123cReAghNGnΩoEp"); // Ω = multi-byte + cstr out = {0}; + + c_forfilter (i, csview, s, utf8_isupper(utf8_peek(i.ref))) { + char chr[4]; + utf8_encode(chr, utf8_tolower(utf8_peek(i.ref))); + cstr_push(&out, chr); + } + + printf(" %s\n", cstr_str(&out)); + cstr_drop(&out); +} + +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); + + c_forfilter (i, crange, R, + c_flt_skip(i,15) && + c_flt_skipwhile(i, flt_mid_decade(i)) && + c_flt_skip(i,30) && + flt_even(i) && + c_flt_take(i,5) + ){ + printf(" %lld", *i.ref); + } + puts(""); +} + +int main(void) +{ + puts("demo1"); demo1(); + puts("demo2"); demo2(); + puts("demo3"); demo3(); + puts("demo4"); demo4(); + puts("demo5"); demo5(); +} diff --git a/misc/examples/algorithms/forloops.c b/misc/examples/algorithms/forloops.c new file mode 100644 index 00000000..72d745f8 --- /dev/null +++ b/misc/examples/algorithms/forloops.c @@ -0,0 +1,69 @@ +#include +#include + +#define i_type IVec +#define i_key int +#include + +#define i_type IMap +#define i_key int +#define i_val int +#include + + +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_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); +} diff --git a/misc/examples/algorithms/random.c b/misc/examples/algorithms/random.c new file mode 100644 index 00000000..b7c0f277 --- /dev/null +++ b/misc/examples/algorithms/random.c @@ -0,0 +1,45 @@ +#include +#include +#include + +int main(void) +{ + const int 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, %d, avg: %f\n", + (double)diff/CLOCKS_PER_SEC, N, (double)sum/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, %d, avg: %f\n", + range, (double)diff/CLOCKS_PER_SEC, N, (double)sum/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, %d, avg: %f\n", + range, (double)diff/CLOCKS_PER_SEC, N, (double)sum/N); + +} diff --git a/misc/examples/algorithms/shape.c b/misc/examples/algorithms/shape.c new file mode 100644 index 00000000..bd4bdd5a --- /dev/null +++ b/misc/examples/algorithms/shape.c @@ -0,0 +1,158 @@ +// Demo of typesafe polymorphism in C99, using STC. + +#include +#include +#include + +#define DYN_CAST(T, s) \ + (&T##_api == (s)->api ? (T*)(s) : (T*)0) + +// Shape definition +// ============================================================ + +typedef struct { + float x, y; +} Point; + +typedef struct Shape Shape; + +struct ShapeAPI { + void (*drop)(Shape*); + void (*draw)(const Shape*); +}; + +struct Shape { + struct ShapeAPI* api; + uint32_t color; + uint16_t style; + uint8_t thickness; + uint8_t hardness; +}; + +void Shape_drop(Shape* shape) +{ + printf("shape destructed\n"); +} + +void Shape_delete(Shape* shape) +{ + if (shape) { + shape->api->drop(shape); + c_free(shape); + } +} + +// Triangle implementation +// ============================================================ + +typedef struct { + Shape shape; + Point p[3]; +} Triangle; + +extern struct ShapeAPI Triangle_api; + + +Triangle Triangle_from(Point a, Point b, Point c) { + Triangle t = {{&Triangle_api}, {a, b, c}}; + return t; +} + +static void Triangle_draw(const Shape* shape) +{ + const Triangle* self = DYN_CAST(Triangle, shape); + printf("Triangle : (%g,%g), (%g,%g), (%g,%g)\n", + (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 = { + .drop = Shape_drop, + .draw = Triangle_draw, +}; + +// Polygon implementation +// ============================================================ + +#define i_type PointVec +#define i_key Point +#include + +typedef struct { + Shape shape; + PointVec points; +} Polygon; + +extern struct ShapeAPI Polygon_api; + + +Polygon Polygon_init(void) { + Polygon p = {{&Polygon_api}, {0}}; + return p; +} + +void Polygon_addPoint(Polygon* self, Point p) +{ + PointVec_push(&self->points, p); +} + +static void Polygon_drop(Shape* shape) +{ + Polygon* self = DYN_CAST(Polygon, shape); + printf("poly destructed\n"); + PointVec_drop(&self->points); +} + +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)", (double)i.ref->x, (double)i.ref->y); + puts(""); +} + +struct ShapeAPI Polygon_api = { + .drop = Polygon_drop, + .draw = Polygon_draw, +}; + +// Test +// ============================================================ + +#define i_type Shapes +#define i_key Shape* +#define i_keydrop(x) Shape_delete(*x) +#define i_no_clone +#include + +void testShape(const Shape* shape) +{ + shape->api->draw(shape); +} + + +int main(void) +{ + Shapes shapes = {0}; + + 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()); + + c_forlist (i, Point, {{50, 72}, {123, 73}, {127, 201}, {828, 333}}) + Polygon_addPoint(pol1, *i.ref); + + c_forlist (i, Point, {{5, 7}, {12, 7}, {12, 20}, {82, 33}, {17, 56}}) + Polygon_addPoint(pol2, *i.ref); + + Shapes_push(&shapes, &tri1->shape); + Shapes_push(&shapes, &pol1->shape); + Shapes_push(&shapes, &pol2->shape); + + c_foreach (i, Shapes, shapes) + testShape(*i.ref); + + Shapes_drop(&shapes); +} diff --git a/misc/examples/algorithms/shape.cpp b/misc/examples/algorithms/shape.cpp new file mode 100644 index 00000000..ea1f53d2 --- /dev/null +++ b/misc/examples/algorithms/shape.cpp @@ -0,0 +1,122 @@ +// Demo of polymorphism in C++ + +#include +#include +#include + +// Shape definition +// ============================================================ + +struct Point { + float x, y; +}; + +std::ostream& operator<<(std::ostream& os, const Point& p) { + os << " (" << p.x << "," << p.y << ")"; + return os; +} + +struct Shape { + virtual ~Shape(); + virtual void draw() const = 0; + + uint32_t color; + uint16_t style; + uint8_t thickness; + uint8_t hardness; +}; + +Shape::~Shape() +{ + std::cout << "base destructed" << std::endl; +} + +// Triangle implementation +// ============================================================ + +struct Triangle : public Shape +{ + Triangle(Point a, Point b, Point c); + void draw() const override; + + private: Point p[3]; +}; + + +Triangle::Triangle(Point a, Point b, Point c) + : p{a, b, c} {} + +void Triangle::draw() const +{ + std::cout << "Triangle :" + << p[0] << p[1] << p[2] + << std::endl; +} + + +// Polygon implementation +// ============================================================ + + +struct Polygon : public Shape +{ + ~Polygon(); + void draw() const override; + void addPoint(const Point& p); + + private: std::vector points; +}; + + +void Polygon::addPoint(const Point& p) +{ + points.push_back(p); +} + +Polygon::~Polygon() +{ + std::cout << "poly destructed" << std::endl; +} + +void Polygon::draw() const +{ + std::cout << "Polygon :"; + for (auto& p : points) + std::cout << p ; + std::cout << std::endl; +} + + +// Test +// ============================================================ + +void testShape(const Shape* shape) +{ + shape->draw(); +} + +#include + +int main(void) +{ + std::vector> shapes; + + auto tri1 = std::make_unique(Point{5, 7}, Point{12, 7}, Point{12, 20}); + auto pol1 = std::make_unique(); + auto pol2 = std::make_unique(); + + for (auto& p: std::array + {{{50, 72}, {123, 73}, {127, 201}, {828, 333}}}) + pol1->addPoint(p); + + for (auto& p: std::array + {{{5, 7}, {12, 7}, {12, 20}, {82, 33}, {17, 56}}}) + pol2->addPoint(p); + + shapes.push_back(std::move(tri1)); + shapes.push_back(std::move(pol1)); + shapes.push_back(std::move(pol2)); + + for (auto& shape: shapes) + testShape(shape.get()); +} diff --git a/misc/examples/arc_containers.c b/misc/examples/arc_containers.c deleted file mode 100644 index 2fb04c56..00000000 --- a/misc/examples/arc_containers.c +++ /dev/null @@ -1,81 +0,0 @@ -// Create a stack and a list of shared pointers to maps, -// and demonstrate sharing and cloning of maps. -#define i_implement -#include -#include -#define i_type Map -#define i_key_str // strings -#define i_val int -#define i_keydrop(p) (printf("drop name: %s\n", cstr_str(p)), cstr_drop(p)) -#include - -#define i_type Arc // (atomic) ref. counted type -#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 -#include - -#define i_type Stack -#define i_keyboxed Arc // define i_keyboxed for carc/cbox value (not i_key) -#include - -#define i_type List -#define i_keyboxed Arc // as above -#include - -int main(void) -{ - Stack stack = {0}; - List list = {0}; - c_defer( - Stack_drop(&stack), - List_drop(&list) - ){ - // POPULATE stack with shared pointers to Maps: - Map *map; - map = Stack_push(&stack, Arc_from(Map_init()))->get; - Map_emplace(map, "Joey", 1990); - Map_emplace(map, "Mary", 1995); - Map_emplace(map, "Joanna", 1992); - - map = Stack_push(&stack, Arc_from(Map_init()))->get; - Map_emplace(map, "Rosanna", 2001); - Map_emplace(map, "Brad", 1999); - Map_emplace(map, "Jack", 1980); - - // POPULATE list: - map = List_push_back(&list, Arc_from(Map_init()))->get; - Map_emplace(map, "Steve", 1979); - Map_emplace(map, "Rick", 1974); - Map_emplace(map, "Tracy", 2003); - - // Share two Maps from the stack with the list using emplace (clone the carc): - List_push_back(&list, Arc_clone(stack.data[0])); - List_push_back(&list, Arc_clone(stack.data[1])); - - // Clone (deep copy) a Map from the stack to the list - // List will contain two shared and two unshared maps. - map = List_push_back(&list, Arc_from(Map_clone(*stack.data[1].get)))->get; - - // Add one more element to the cloned map: - Map_emplace_or_assign(map, "CLONED", 2021); - - // Add one more element to the shared map: - Map_emplace_or_assign(stack.data[1].get, "SHARED", 2021); - - puts("STACKS"); - c_foreach (i, Stack, stack) { - c_forpair (name, year, Map, *i.ref->get) - printf(" %s:%d", cstr_str(_.name), *_.year); - puts(""); - } - - puts("LIST"); - c_foreach (i, List, list) { - c_forpair (name, year, Map, *i.ref->get) - printf(" %s:%d", cstr_str(_.name), *_.year); - puts(""); - } - } -} diff --git a/misc/examples/arc_demo.c b/misc/examples/arc_demo.c deleted file mode 100644 index 929a48a1..00000000 --- a/misc/examples/arc_demo.c +++ /dev/null @@ -1,62 +0,0 @@ -#include -#include - -void int_drop(int* x) { - printf("drop: %d\n", *x); -} - -// carc implements its own clone method using reference counting, -// 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_key int -#define i_keydrop int_drop // optional, just to display the elements destroyed -#define i_cmp_native // use int comparison (x < y, x == y). -#include // Arc - -#define i_keyboxed Arc // note: use i_keyboxed instead of i_key for carc/cbox elements -#include // csset_Arc (like: std::set>) - -#define i_keyboxed Arc // note: as above. -#include // cvec_Arc (like: std::vector>) - -int main(void) -{ - const int years[] = {2021, 2012, 2022, 2015}; - - cvec_Arc vec = {0}; - 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) - printf(" %d", *i.ref->get); - puts(""); - - // add odd numbers from vec to set - csset_Arc set = {0}; - c_foreach (i, cvec_Arc, vec) - if (*i.ref->get & 1) - csset_Arc_insert(&set, Arc_clone(*i.ref)); // copy shared pointer => increments counter. - - // erase the two last elements in vec - cvec_Arc_pop_back(&vec); - cvec_Arc_pop_back(&vec); - - printf("vec:"); - c_foreach (i, cvec_Arc, vec) printf(" %d", *i.ref->get); - - printf("\nset:"); - c_foreach (i, csset_Arc, set) printf(" %d", *i.ref->get); - - Arc p = Arc_clone(vec.data[0]); - printf("\n%d is now owned by %ld objects\n", *p.get, *p.use_count); - - Arc_drop(&p); - cvec_Arc_drop(&vec); - csset_Arc_drop(&set); -} diff --git a/misc/examples/arcvec_erase.c b/misc/examples/arcvec_erase.c deleted file mode 100644 index ba54c1c7..00000000 --- a/misc/examples/arcvec_erase.c +++ /dev/null @@ -1,50 +0,0 @@ -#include - -void show_drop(int* x) { printf("drop: %d\n", *x); } - -#define i_type Arc -#define i_key int -#define i_keydrop show_drop -#define i_cmp_native // enable sort/search for int type -#include // Shared pointer to int - -#define i_type Vec -#define i_keyboxed Arc -#include // Vec: cvec - - -int main(void) -{ - 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])); - - printf("vec before erase :"); - c_foreach (i, Vec, vec) - printf(" %d", *i.ref->get); - - printf("\nerase vec.data[2]; or first matching value depending on compare.\n"); - Vec_iter it; - it = Vec_find(&vec, *vec.data[2].get); - if (it.ref) - Vec_erase_at(&vec, it); - - int year = 2015; - it = Vec_find(&vec, year); // Ok as tmp only. - if (it.ref) - Vec_erase_at(&vec, it); - - printf("vec after erase :"); - c_foreach (i, Vec, vec) - printf(" %d", *i.ref->get); - - Vec_sort(&vec); - printf("\nvec after sort :"); - c_foreach (i, Vec, vec) - printf(" %d", *i.ref->get); - - puts("\nDone"); - Vec_drop(&vec); -} diff --git a/misc/examples/astar.c b/misc/examples/astar.c deleted file mode 100644 index 590b7952..00000000 --- a/misc/examples/astar.c +++ /dev/null @@ -1,174 +0,0 @@ -// -// -- An A* pathfinder inspired by the excellent tutorial at Red Blob Games -- -// -// 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 -#include - -typedef struct -{ - int x; - int y; - int priorty; - int width; -} -point; - -point -point_init(int x, int y, int width) -{ - return c_LITERAL(point){ x, y, 0, width }; -} - -int -point_cmp_priority(const point* a, const point* b) -{ - return c_default_cmp(&a->priorty, &b->priorty); -} - -int -point_equal(const point* a, const point* b) -{ - return a->x == b->x && a->y == b->y; -} - -point -point_from(const cstr* maze, const char* c, int width) -{ - int index = (int)cstr_find(maze, c); - return point_init(index % width, index / width, width); -} - -int -point_index(const point* p) -{ - return p->x + p->width * p->y; -} - -int -point_key_cmp(const point* a, const point* b) -{ - int i = point_index(a); - int j = point_index(b); - return (i == j) ? 0 : (i < j) ? -1 : 1; -} - -#define i_key point -#define i_cmp point_cmp_priority -#include - -#define i_key point -#define i_opt c_no_cmp -#include - -#define i_key point -#define i_val int -#define i_cmp point_key_cmp -#define i_tag pcost -#include - -#define i_key point -#define i_val point -#define i_cmp point_key_cmp -#define i_tag pstep -#include - -cdeq_point -astar(cstr* maze, int width) -{ - cdeq_point ret_path = {0}; - - cpque_point front = {0}; - csmap_pstep from = {0}; - csmap_pcost costs = {0}; - c_defer( - cpque_point_drop(&front), - csmap_pstep_drop(&from), - csmap_pcost_drop(&costs) - ){ - point start = point_from(maze, "@", width); - point goal = point_from(maze, "!", width); - csmap_pcost_insert(&costs, start, 0); - cpque_point_push(&front, start); - while (!cpque_point_empty(&front)) - { - point current = *cpque_point_top(&front); - cpque_point_pop(&front); - if (point_equal(¤t, &goal)) - break; - point deltas[] = { - { -1, +1, 0, width }, { 0, +1, 0, width }, { 1, +1, 0, width }, - { -1, 0, 0, width }, /* ~ ~ ~ ~ ~ ~ ~ */ { 1, 0, 0, width }, - { -1, -1, 0, width }, { 0, -1, 0, width }, { 1, -1, 0, width }, - }; - for (size_t i = 0; i < c_arraylen(deltas); i++) - { - point delta = deltas[i]; - point next = point_init(current.x + delta.x, current.y + delta.y, width); - int new_cost = *csmap_pcost_at(&costs, current); - if (cstr_str(maze)[point_index(&next)] != '#') - { - const csmap_pcost_value *cost = csmap_pcost_get(&costs, next); - if (cost == NULL || new_cost < cost->second) - { - csmap_pcost_insert(&costs, next, new_cost); - next.priorty = new_cost + abs(goal.x - next.x) + abs(goal.y - next.y); - cpque_point_push(&front, next); - csmap_pstep_insert(&from, next, current); - } - } - } - } - point current = goal; - while (!point_equal(¤t, &start)) - { - cdeq_point_push_front(&ret_path, current); - current = *csmap_pstep_at(&from, current); - } - cdeq_point_push_front(&ret_path, start); - } - return ret_path; -} - -int -main(void) -{ - cstr maze = cstr_lit( - "#########################################################################\n" - "# # # # # # #\n" - "# # ######### # ##### ######### ##### ##### ##### # ! #\n" - "# # # # # # # # # #\n" - "######### # ######### ######### ##### # # # ######### #\n" - "# # # # # # # # # # #\n" - "# # ############# # # ######### ##### # ######### # #\n" - "# # # # # # # # # #\n" - "# ############# ##### ##### # ##### ######### # ##### #\n" - "# # # # # # # # # #\n" - "# ##### ##### # ##### # ######### # # # #############\n" - "# # # # # # # # # # # #\n" - "############# # # # ######### # ##### # ##### ##### #\n" - "# # # # # # # # # #\n" - "# ##### # ######### ##### # ##### ##### ############# #\n" - "# # # # # # # # # #\n" - "# # ######### # ##### ######### # # ############# # #\n" - "# # # # # # # # # # #\n" - "# ######### # # # ##### ######### ######### # #########\n" - "# # # # # # # # # #\n" - "# @ # ##### ##### ##### ######### ##### # ######### # #\n" - "# # # # # # #\n" - "#########################################################################\n" - ); - int width = (int)cstr_find(&maze, "\n") + 1; - cdeq_point ret_path = astar(&maze, width); - - c_foreach (it, cdeq_point, ret_path) - cstr_data(&maze)[point_index(it.ref)] = 'x'; - - printf("%s", cstr_str(&maze)); - - cdeq_point_drop(&ret_path); - cstr_drop(&maze); -} diff --git a/misc/examples/birthday.c b/misc/examples/birthday.c deleted file mode 100644 index 4742cb45..00000000 --- a/misc/examples/birthday.c +++ /dev/null @@ -1,68 +0,0 @@ -#include -#include -#include -#include - -#define i_tag ic -#define i_key uint64_t -#define i_val int -#include - -static uint64_t seed = 12345; - -static void test_repeats(void) -{ - enum {BITS = 46, BITS_TEST = BITS/2 + 2}; - 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); - - cmap_ic m = cmap_ic_with_capacity(N); - c_forrange (i, N) { - uint64_t k = crand_u64(&rng) & mask; - int v = cmap_ic_insert(&m, k, 0).ref->second += 1; - if (v > 1) printf("repeated value %" PRIu64 " (%d) at 2^%d\n", - k, v, (int)log2((double)i)); - } - cmap_ic_drop(&m); -} - -#define i_key uint32_t -#define i_val uint64_t -#define i_tag x -#include - -void test_distribution(void) -{ - enum {BITS = 26}; - printf("distribution test: 2^%d values\n", BITS); - crand_t rng = crand_init(seed); - const size_t N = 1ull << BITS ; - - cmap_x map = {0}; - c_forrange (N) { - uint64_t k = crand_u64(&rng); - cmap_x_insert(&map, k & 0xf, 0).ref->second += 1; - } - - uint64_t sum = 0; - c_foreach (i, cmap_x, map) sum += i.ref->second; - sum /= (uint64_t)map.size; - - c_foreach (i, cmap_x, map) { - printf("%4" PRIu32 ": %" PRIu64 " - %" PRIu64 ": %11.8f\n", - i.ref->first, i.ref->second, sum, - (1.0 - (double)i.ref->second / (double)sum)); - } - - cmap_x_drop(&map); -} - -int main(void) -{ - seed = (uint64_t)time(NULL); - test_distribution(); - test_repeats(); -} diff --git a/misc/examples/bits.c b/misc/examples/bits.c deleted file mode 100644 index e0a11346..00000000 --- a/misc/examples/bits.c +++ /dev/null @@ -1,66 +0,0 @@ -#include -#include - -int main(void) -{ - cbits set = cbits_with_size(23, true); - cbits s2; - c_defer( - cbits_drop(&set), - cbits_drop(&s2) - ){ - 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: %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("%4lld: ", cbits_size(&set)); - c_forrange (i, cbits_size(&set)) - printf("%d", cbits_test(&set, i)); - puts(""); - - cbits_set(&set, 28); - cbits_resize(&set, 77, true); - cbits_resize(&set, 93, false); - cbits_resize(&set, 102, true); - cbits_set_value(&set, 99, false); - printf("%4lld: ", cbits_size(&set)); - c_forrange (i, cbits_size(&set)) - printf("%d", cbits_test(&set, i)); - - puts("\nIterate:"); - printf("%4lld: ", cbits_size(&set)); - c_forrange (i, cbits_size(&set)) - printf("%d", cbits_test(&set, i)); - puts(""); - - // Make a clone - s2 = cbits_clone(set); - cbits_flip_all(&s2); - cbits_set(&s2, 16); - cbits_set(&s2, 17); - cbits_set(&s2, 18); - printf(" new: "); - c_forrange (i, cbits_size(&s2)) - printf("%d", cbits_test(&s2, i)); - puts(""); - - printf(" xor: "); - cbits_xor(&set, &s2); - c_forrange (i, cbits_size(&set)) - printf("%d", cbits_test(&set, i)); - puts(""); - - cbits_set_all(&set, false); - 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/bits2.c deleted file mode 100644 index de2f16f4..00000000 --- a/misc/examples/bits2.c +++ /dev/null @@ -1,41 +0,0 @@ -#include -// Example of static sized (stack allocated) bitsets - -#define i_type Bits -#define i_capacity 80 // enable fixed bitset on the stack -#include - -int main(void) -{ - Bits s1 = Bits_from("1110100110111"); - - printf("size %lld\n", Bits_size(&s1)); - char buf[256]; - Bits_to_str(&s1, buf, 0, 256); - 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)); - - Bits s2 = Bits_clone(s1); - - Bits_flip_all(&s2); - Bits_reset(&s2, 66); - Bits_reset(&s2, 67); - printf(" s2: "); - c_forrange (i, Bits_size(&s2)) - printf("%d", Bits_test(&s2, i)); - puts(""); - - printf("xor: "); - Bits_xor(&s1, &s2); - c_forrange (i, Bits_size(&s1)) - printf("%d", Bits_test(&s1, i)); - puts(""); - - printf("all: "); - Bits_set_pattern(&s1, 0x3333333333333333); - c_forrange (i, Bits_size(&s1)) - printf("%d", Bits_test(&s1, i)); - puts(""); -} diff --git a/misc/examples/bitsets/bits.c b/misc/examples/bitsets/bits.c new file mode 100644 index 00000000..e0a11346 --- /dev/null +++ b/misc/examples/bitsets/bits.c @@ -0,0 +1,66 @@ +#include +#include + +int main(void) +{ + cbits set = cbits_with_size(23, true); + cbits s2; + c_defer( + cbits_drop(&set), + cbits_drop(&s2) + ){ + 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: %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("%4lld: ", cbits_size(&set)); + c_forrange (i, cbits_size(&set)) + printf("%d", cbits_test(&set, i)); + puts(""); + + cbits_set(&set, 28); + cbits_resize(&set, 77, true); + cbits_resize(&set, 93, false); + cbits_resize(&set, 102, true); + cbits_set_value(&set, 99, false); + printf("%4lld: ", cbits_size(&set)); + c_forrange (i, cbits_size(&set)) + printf("%d", cbits_test(&set, i)); + + puts("\nIterate:"); + printf("%4lld: ", cbits_size(&set)); + c_forrange (i, cbits_size(&set)) + printf("%d", cbits_test(&set, i)); + puts(""); + + // Make a clone + s2 = cbits_clone(set); + cbits_flip_all(&s2); + cbits_set(&s2, 16); + cbits_set(&s2, 17); + cbits_set(&s2, 18); + printf(" new: "); + c_forrange (i, cbits_size(&s2)) + printf("%d", cbits_test(&s2, i)); + puts(""); + + printf(" xor: "); + cbits_xor(&set, &s2); + c_forrange (i, cbits_size(&set)) + printf("%d", cbits_test(&set, i)); + puts(""); + + cbits_set_all(&set, false); + printf("%4lld: ", cbits_size(&set)); + c_forrange (i, cbits_size(&set)) + printf("%d", cbits_test(&set, i)); + puts(""); + } +} diff --git a/misc/examples/bitsets/bits2.c b/misc/examples/bitsets/bits2.c new file mode 100644 index 00000000..de2f16f4 --- /dev/null +++ b/misc/examples/bitsets/bits2.c @@ -0,0 +1,41 @@ +#include +// Example of static sized (stack allocated) bitsets + +#define i_type Bits +#define i_capacity 80 // enable fixed bitset on the stack +#include + +int main(void) +{ + Bits s1 = Bits_from("1110100110111"); + + printf("size %lld\n", Bits_size(&s1)); + char buf[256]; + Bits_to_str(&s1, buf, 0, 256); + 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)); + + Bits s2 = Bits_clone(s1); + + Bits_flip_all(&s2); + Bits_reset(&s2, 66); + Bits_reset(&s2, 67); + printf(" s2: "); + c_forrange (i, Bits_size(&s2)) + printf("%d", Bits_test(&s2, i)); + puts(""); + + printf("xor: "); + Bits_xor(&s1, &s2); + c_forrange (i, Bits_size(&s1)) + printf("%d", Bits_test(&s1, i)); + puts(""); + + printf("all: "); + Bits_set_pattern(&s1, 0x3333333333333333); + c_forrange (i, Bits_size(&s1)) + printf("%d", Bits_test(&s1, i)); + puts(""); +} diff --git a/misc/examples/bitsets/prime.c b/misc/examples/bitsets/prime.c new file mode 100644 index 00000000..cb3b095a --- /dev/null +++ b/misc/examples/bitsets/prime.c @@ -0,0 +1,56 @@ +#include +#include +#include +#include +#include +#include + + +cbits sieveOfEratosthenes(int64_t 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; + 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) + cbits_reset(&bits, j>>1); + } + return bits; +} + +int main(void) +{ + int n = 1000000000; + printf("Computing prime numbers up to %d\n", n); + + clock_t t = clock(); + cbits primes = sieveOfEratosthenes(n + 1); + int np = (int)cbits_count(&primes); + t = clock() - t; + + puts("Show all the primes in the range [2, 1000):"); + printf("2"); + c_forrange (i, 3, 1000, 2) + if (cbits_test(&primes, i>>1)) printf(" %lld", i); + puts("\n"); + + puts("Show the last 50 primes using a temporary crange generator:"); + crange range = crange_make(n - 1, 0, -2); + + c_forfilter (i, crange, range, + cbits_test(&primes, *i.ref/2) && + c_flt_take(i, 50) + ){ + printf("%lld ", *i.ref); + if (c_flt_getcount(i) % 10 == 0) puts(""); + } + printf("Number of primes: %d, time: %.2f\n\n", np, (double)t/CLOCKS_PER_SEC); + + cbits_drop(&primes); +} diff --git a/misc/examples/books.c b/misc/examples/books.c deleted file mode 100644 index 1fd57f27..00000000 --- a/misc/examples/books.c +++ /dev/null @@ -1,62 +0,0 @@ -// https://doc.rust-lang.org/std/collections/struct.HashMap.html -#define i_implement -#include -#define i_key_str -#define i_val_str -#include - -// Type inference lets us omit an explicit type signature (which -// would be `HashMap` in this example). -int main(void) -{ - cmap_str book_reviews = {0}; - - // Review some books. - cmap_str_emplace(&book_reviews, - "Adventures of Huckleberry Finn", - "My favorite book." - ); - cmap_str_emplace(&book_reviews, - "Grimms' Fairy Tales", - "Masterpiece." - ); - cmap_str_emplace(&book_reviews, - "Pride and Prejudice", - "Very enjoyable" - ); - cmap_str_insert(&book_reviews, - cstr_lit("The Adventures of Sherlock Holmes"), - cstr_lit("Eye lyked it alot.") - ); - - // Check for a specific one. - // When collections store owned values (String), they can still be - // queried using references (&str). - if (cmap_str_contains(&book_reviews, "Les Misérables")) { - printf("We've got %" c_ZI " reviews, but Les Misérables ain't one.", - cmap_str_size(&book_reviews)); - } - - // oops, this review has a lot of spelling mistakes, let's delete it. - cmap_str_erase(&book_reviews, "The Adventures of Sherlock Holmes"); - - // Look up the values associated with some keys. - const char* to_find[] = {"Pride and Prejudice", "Alice's Adventure in Wonderland"}; - c_forrange (i, c_arraylen(to_find)) { - const cmap_str_value* b = cmap_str_get(&book_reviews, to_find[i]); - if (b) - printf("%s: %s\n", cstr_str(&b->first), cstr_str(&b->second)); - else - printf("%s is unreviewed.\n", to_find[i]); - } - - // Look up the value for a key (will panic if the key is not found). - printf("Review for Jane: %s\n", cstr_str(cmap_str_at(&book_reviews, "Pride and Prejudice"))); - - // Iterate over everything. - c_forpair (book, review, cmap_str, book_reviews) { - printf("%s: \"%s\"\n", cstr_str(_.book), cstr_str(_.review)); - } - - cmap_str_drop(&book_reviews); -} diff --git a/misc/examples/box.c b/misc/examples/box.c deleted file mode 100644 index 94d126c0..00000000 --- a/misc/examples/box.c +++ /dev/null @@ -1,69 +0,0 @@ -/* cbox: heap allocated boxed type */ -#define i_implement -#include - -typedef struct { cstr name, last; } Person; - -Person Person_make(const char* name, const char* last) { - return c_LITERAL(Person){.name = cstr_from(name), .last = cstr_from(last)}; -} - -uint64_t Person_hash(const Person* a) { - return cstr_hash(&a->name) ^ cstr_hash(&a->last); -} - -int Person_cmp(const Person* a, const Person* b) { - int c = cstr_cmp(&a->name, &b->name); - return c ? c : cstr_cmp(&a->last, &b->last); -} - -Person Person_clone(Person p) { - p.name = cstr_clone(p.name); - p.last = cstr_clone(p.last); - return p; -} - -void Person_drop(Person* p) { - printf("drop: %s %s\n", cstr_str(&p->name), cstr_str(&p->last)); - c_drop(cstr, &p->name, &p->last); -} - -#define i_type PBox -#define i_keyclass Person // "class" binds _cmp, _clone, _drop functions. -#include - -#define i_type Persons -#define i_keyboxed PBox // "arcbox" informs that PBox is a smart pointer. -#include - -int main(void) -{ - Persons vec = {0}; - PBox p = PBox_from(Person_make("Laura", "Palmer")); - PBox q = PBox_clone(p); - cstr_assign(&q.get->name, "Leland"); - - printf("orig: %s %s\n", cstr_str(&p.get->name), cstr_str(&p.get->last)); - printf("copy: %s %s\n", cstr_str(&q.get->name), cstr_str(&q.get->last)); - - Persons_emplace(&vec, Person_make("Dale", "Cooper")); - Persons_emplace(&vec, Person_make("Audrey", "Home")); - - // NB! Clone/share p and q in the Persons container. - Persons_push(&vec, PBox_clone(p)); - Persons_push(&vec, PBox_clone(q)); - - c_foreach (i, Persons, vec) - printf("%s %s\n", cstr_str(&i.ref->get->name), cstr_str(&i.ref->get->last)); - puts(""); - - // Look-up Audrey! Create a temporary Person for lookup. - Person a = Person_make("Audrey", "Home"); - const PBox *v = Persons_get(&vec, a); // lookup - if (v) printf("found: %s %s\n", cstr_str(&v->get->name), cstr_str(&v->get->last)); - - Person_drop(&a); - PBox_drop(&p); - PBox_drop(&q); - Persons_drop(&vec); -} diff --git a/misc/examples/box2.c b/misc/examples/box2.c deleted file mode 100644 index eaab1c47..00000000 --- a/misc/examples/box2.c +++ /dev/null @@ -1,82 +0,0 @@ -// example: https://doc.rust-lang.org/rust-by-example/std/box.html -#include - -typedef struct { - double x; - double y; -} Point; - -// A Rectangle can be specified by where its top left and bottom right -// corners are in space -typedef struct { - Point top_left; - Point bottom_right; -} Rectangle; - -#define i_key Point -#include // cbox_Point - -#define i_key Rectangle -#include // cbox_Rectangle - -// Box in box: -#define i_type BoxBoxPoint -#define i_keyboxed cbox_Point // NB: use i_keyboxed when value is a cbox or carc! -#define i_no_cmp -#include // BoxBoxPoint - -Point origin(void) { - 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(c_LITERAL(Point){ .x=1.0, .y=2.0 }); -} - - -int main(void) { - // Stack allocated variables - Point point = origin(); - Rectangle rectangle = { - .top_left = origin(), - .bottom_right = { .x=3.0, .y=-4.0 } - }; - - // Heap allocated rectangle - cbox_Rectangle boxed_rectangle = cbox_Rectangle_make(c_LITERAL(Rectangle){ - .top_left = origin(), - .bottom_right = { .x=3.0, .y=-4.0 } - }); - // The output of functions can be boxed - cbox_Point boxed_point = cbox_Point_make(origin()); - - // Can use from(raw) and toraw instead: - BoxBoxPoint box_in_a_box = BoxBoxPoint_from(origin()); - - c_defer( - BoxBoxPoint_drop(&box_in_a_box), - cbox_Point_drop(&boxed_point), - cbox_Rectangle_drop(&boxed_rectangle) - ){ - printf("box_in_a_box: x = %g\n", BoxBoxPoint_toraw(&box_in_a_box).x); - - printf("Point occupies %d bytes on the stack\n", - (int)sizeof(point)); - printf("Rectangle occupies %d bytes on the stack\n", - (int)sizeof(rectangle)); - - // box size == pointer size - printf("Boxed point occupies %d bytes on the stack\n", - (int)sizeof(boxed_point)); - printf("Boxed rectangle occupies %d bytes on the stack\n", - (int)sizeof(boxed_rectangle)); - printf("Boxed box occupies %d bytes on the stack\n", - (int)sizeof(box_in_a_box)); - - // Copy the data contained in `boxed_point` into `unboxed_point` - Point unboxed_point = *boxed_point.get; - printf("Unboxed point occupies %d bytes on the stack\n", - (int)sizeof(unboxed_point)); - } -} diff --git a/misc/examples/cointerleave.c b/misc/examples/cointerleave.c deleted file mode 100644 index 599ceaab..00000000 --- a/misc/examples/cointerleave.c +++ /dev/null @@ -1,62 +0,0 @@ -// https://www.youtube.com/watch?v=8sEe-4tig_A -#include -#include -#define i_type IVec -#define i_key int -#include - -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_block_on(interleaved(&g)) { - printf("%d ", g.value); - } - puts(""); - c_drop(IVec, &a, &b); -} - -int main(void) -{ - Use(); -} diff --git a/misc/examples/complex.c b/misc/examples/complex.c deleted file mode 100644 index 4eb1574b..00000000 --- a/misc/examples/complex.c +++ /dev/null @@ -1,49 +0,0 @@ - -// Define similar c++ data types: -// -// using FloatStack = std::stack; -// using StackList = std::stack; -// using ListMap = std::unordered_map>; -// using MapMap = std::unordered_map; -#define i_implement -#include - -#define i_type FloatStack -#define i_key float -#include - -#define i_type StackList -#define i_keyclass FloatStack // "class" picks up _clone, _drop, _cmp -#define i_opt c_no_cmp // exclude FloatStack_cmp(): not defined -#include - -#define i_type ListMap -#define i_key int -#define i_valclass StackList // "class" picks up _clone, _drop -#include - -#define i_type MapMap -#define i_key_str -#define i_valclass ListMap -#include - - -int main(void) -{ - MapMap mmap = {0}; - - // Put in some data in the structures - ListMap* lmap = &MapMap_emplace(&mmap, "first", ListMap_init()).ref->second; - StackList* list = &ListMap_insert(lmap, 42, StackList_init()).ref->second; - FloatStack* stack = StackList_push_back(list, FloatStack_with_size(10, 0)); - stack->data[3] = 3.1415927f; - printf("stack size: %" c_ZI "\n", FloatStack_size(stack)); - - // Access the data entry - 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", (double)*FloatStack_at(stack_p, 3)); // pi - - MapMap_drop(&mmap); -} diff --git a/misc/examples/convert.c b/misc/examples/convert.c deleted file mode 100644 index fa64560e..00000000 --- a/misc/examples/convert.c +++ /dev/null @@ -1,57 +0,0 @@ -#define i_implement -#include - -#define i_key_str -#define i_val_str -#include - -#define i_key_str -#include - -#define i_key_str -#include - -int main(void) -{ - cmap_str map, mclone; - cvec_str keys = {0}, values = {0}; - clist_str list = {0}; - - c_defer( - cmap_str_drop(&map), - cmap_str_drop(&mclone), - cvec_str_drop(&keys), - cvec_str_drop(&values), - clist_str_drop(&list) - ){ - map = c_init(cmap_str, { - {"green", "#00ff00"}, - {"blue", "#0000ff"}, - {"yellow", "#ffff00"}, - }); - - puts("MAP:"); - c_foreach (i, cmap_str, map) - printf(" %s: %s\n", cstr_str(&i.ref->first), cstr_str(&i.ref->second)); - - puts("\nCLONE MAP:"); - mclone = cmap_str_clone(map); - c_foreach (i, cmap_str, mclone) - printf(" %s: %s\n", cstr_str(&i.ref->first), cstr_str(&i.ref->second)); - - puts("\nCOPY MAP TO VECS:"); - c_foreach (i, cmap_str, mclone) { - cvec_str_emplace_back(&keys, cstr_str(&i.ref->first)); - cvec_str_emplace_back(&values, cstr_str(&i.ref->second)); - } - c_forrange (i, cvec_str_size(&keys)) - printf(" %s: %s\n", cstr_str(keys.data + i), cstr_str(values.data + i)); - - puts("\nCOPY VEC TO LIST:"); - c_foreach (i, cvec_str, keys) - clist_str_emplace_back(&list, cstr_str(i.ref)); - - c_foreach (i, clist_str, list) - printf(" %s\n", cstr_str(i.ref)); - } -} diff --git a/misc/examples/coread.c b/misc/examples/coread.c deleted file mode 100644 index a13f6be5..00000000 --- a/misc/examples/coread.c +++ /dev/null @@ -1,41 +0,0 @@ -#define i_implement -#include -#include -#include - -// 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_cleanup: - 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_block_on(file_read(&g)) - { - printf("%3d %s\n", ++n, cstr_str(&g.line)); - //if (n == 10) cco_stop(&g); - } -} diff --git a/misc/examples/coroutines.c b/misc/examples/coroutines.c deleted file mode 100644 index b8dfaa13..00000000 --- a/misc/examples/coroutines.c +++ /dev/null @@ -1,112 +0,0 @@ -#include -#include -#include - -// 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_cleanup: - 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_cleanup: - 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_on(prime(&g->prm)); - cco_await_on(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_on(prime(&g->prm)); - - cco_cleanup: - puts("final combined"); - } - return 0; -} - -int main(void) -{ - struct combined c = {.prm={.count=8}, .fib={14}}; - int res; - - cco_block_on(combined(&c), &res) { - 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/cointerleave.c b/misc/examples/coroutines/cointerleave.c new file mode 100644 index 00000000..599ceaab --- /dev/null +++ b/misc/examples/coroutines/cointerleave.c @@ -0,0 +1,62 @@ +// https://www.youtube.com/watch?v=8sEe-4tig_A +#include +#include +#define i_type IVec +#define i_key int +#include + +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_block_on(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..a13f6be5 --- /dev/null +++ b/misc/examples/coroutines/coread.c @@ -0,0 +1,41 @@ +#define i_implement +#include +#include +#include + +// 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_cleanup: + 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_block_on(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..b8dfaa13 --- /dev/null +++ b/misc/examples/coroutines/coroutines.c @@ -0,0 +1,112 @@ +#include +#include +#include + +// 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_cleanup: + 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_cleanup: + 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_on(prime(&g->prm)); + cco_await_on(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_on(prime(&g->prm)); + + cco_cleanup: + puts("final combined"); + } + return 0; +} + +int main(void) +{ + struct combined c = {.prm={.count=8}, .fib={14}}; + int res; + + cco_block_on(combined(&c), &res) { + 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..c87582f1 --- /dev/null +++ b/misc/examples/coroutines/cotasks1.c @@ -0,0 +1,100 @@ +// https://mariusbancila.ro/blog/2020/06/22/a-cpp20-coroutine-example/ + +#include +#include +#define i_static +#include +#include + +struct next_value { + int val; + int cco_state; + cco_timer tm; +}; + +int next_value(struct next_value* co) +{ + cco_routine (co) { + while (true) { + cco_timer_await(&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 str; + int cco_state; +}; + +int produce_items(struct produce_items* p) +{ + cco_routine (p) { + p->str = cstr_null; + while (true) + { + cco_await(next_value(&p->next) != CCO_AWAIT); + cstr_printf(&p->str, "item %d", p->next.val); + print_time(); + printf("produced %s\n", cstr_str(&p->str)); + cco_yield(); + } + cco_cleanup: + cstr_drop(&p->str); + 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->str)); + } + cco_cleanup: + puts("done consume"); + } + return 0; +} + +int main(void) +{ + struct produce_items produce = {0}; + struct consume_items consume = {.n=5}; + int count = 0; + + cco_block_on(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..293583bc --- /dev/null +++ b/misc/examples/coroutines/cotasks2.c @@ -0,0 +1,103 @@ +// https://mariusbancila.ro/blog/2020/06/22/a-cpp20-coroutine-example/ + +#include +#include +#define i_static +#include +#include + +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_timer_await(&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 str; +); + +int produce_items(struct produce_items* p, cco_runtime* rt) +{ + cco_routine (p) { + p->str = cstr_null; + while (true) + { + // await for next CCO_YIELD in next_value() + cco_await_task(&p->next, rt, CCO_YIELD); + cstr_printf(&p->str, "item %d", p->next.val); + print_time(); + printf("produced %s\n", cstr_str(&p->str)); + cco_yield(); + } + cco_cleanup: + cstr_drop(&p->str); + 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) { + 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.str)); + } + cco_cleanup: + cco_stop(&c->produce); + cco_resume(&c->produce, rt); + puts("done consume"); + } + return 0; +} + +int main(void) +{ + struct consume_items consume = { + .n=5, + .cco_fn=consume_items, + .produce={.cco_fn=produce_items, .next={.cco_fn=next_value}}, + }; + int count = 0; + + cco_block_task(&consume) + { + ++count; + //cco_sleep(0.001); + //if (consume.i == 3) + // cco_stop(&consume); + } + printf("count: %d\n", count); +} \ No newline at end of file diff --git a/misc/examples/coroutines/dining_philosophers.c b/misc/examples/coroutines/dining_philosophers.c new file mode 100644 index 00000000..a5063a42 --- /dev/null +++ b/misc/examples/coroutines/dining_philosophers.c @@ -0,0 +1,105 @@ +// https://en.wikipedia.org/wiki/Dining_philosophers_problem +#include +#include +#include +#include + +// 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_timer_await(&p->tm, duration); + + printf("Philosopher %d is hungry...\n", p->id); + cco_sem_await(p->left_fork); + cco_sem_await(p->right_fork); + + duration = 0.5 + crandf(); + printf("Philosopher %d is eating for %.0f minutes...\n", p->id, duration*10); + cco_timer_await(&p->tm, duration); + + cco_sem_release(p->left_fork); + cco_sem_release(p->right_fork); + } + + cco_cleanup: + 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_cleanup: + 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)); + + while (!cco_done(&dine)) { + if (cco_timer_expired(&tm)) + cco_stop(&dine); + dining(&dine); // resume + cco_sleep(0.001); + ++n; + } + printf("n=%d\n", n); +} diff --git a/misc/examples/coroutines/generator.c b/misc/examples/coroutines/generator.c new file mode 100644 index 00000000..a15f9ba5 --- /dev/null +++ b/misc/examples/coroutines/generator.c @@ -0,0 +1,55 @@ +// https://quuxplusone.github.io/blog/2019/03/06/pythagorean-triples/ + +#include +#include + +typedef struct { + int size; + int a, b, c; +} Triple, Triple_value; + +typedef struct { + Triple_value* ref; + int count; + int cco_state; +} Triple_iter; + +int Triple_next(Triple_iter* it) { + Triple_value* g = it->ref; + cco_routine(it) + { + for (g->c = 5; g->size; ++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->size) + cco_return; + cco_yield(); + } + } + } + } + cco_cleanup: + it->ref = NULL; + } + return 0; +} + +Triple_iter Triple_begin(Triple* g) { + Triple_iter it = {.ref=g}; + Triple_next(&it); + return it; +} + + +int main(void) +{ + puts("Pythagorean triples with c < 100:"); + Triple triple = {.size=30}; // max number of triples + c_foreach (i, Triple, triple) { + if (i.ref->c < 100) + printf("%u: (%d, %d, %d)\n", i.count, i.ref->a, i.ref->b, i.ref->c); + else + cco_stop(&i); + } +} diff --git a/misc/examples/coroutines/scheduler.c b/misc/examples/coroutines/scheduler.c new file mode 100644 index 00000000..38defd0f --- /dev/null +++ b/misc/examples/coroutines/scheduler.c @@ -0,0 +1,74 @@ +// https://www.youtube.com/watch?v=8sEe-4tig_A +#include +#include + +struct Task { + int (*fn)(struct Task*); + int cco_state; + struct Scheduler* sched; +}; + +#define i_type Scheduler +#define i_key struct Task +#include + +static bool schedule(Scheduler* sched) +{ + struct Task task = *Scheduler_front(sched); + Scheduler_pop(sched); + + if (!cco_done(&task)) + task.fn(&task); + + return !Scheduler_empty(sched); +} + +static int push_task(const struct Task* task) +{ + Scheduler_push(task->sched, *task); + return CCO_YIELD; +} + + +static int taskA(struct Task* task) +{ + cco_routine(task) { + puts("Hello, from task A"); + cco_yield_v(push_task(task)); + puts("A is back doing work"); + cco_yield_v(push_task(task)); + puts("A is back doing more work"); + cco_yield_v(push_task(task)); + puts("A is back doing even more work"); + } + return 0; +} + +static int taskB(struct Task* task) +{ + cco_routine(task) { + puts("Hello, from task B"); + cco_yield_v(push_task(task)); + puts("B is back doing work"); + cco_yield_v(push_task(task)); + puts("B is back doing more work"); + } + return 0; +} + +void Use(void) +{ + Scheduler scheduler = c_init(Scheduler, { + {.fn=taskA, .sched=&scheduler}, + {.fn=taskB, .sched=&scheduler}, + }); + + while (schedule(&scheduler)) {} + + Scheduler_drop(&scheduler); +} + +int main(void) +{ + Use(); +} diff --git a/misc/examples/coroutines/triples.c b/misc/examples/coroutines/triples.c new file mode 100644 index 00000000..9f2fcc1e --- /dev/null +++ b/misc/examples/coroutines/triples.c @@ -0,0 +1,72 @@ +// https://quuxplusone.github.io/blog/2019/03/06/pythagorean-triples/ + +#include +#include + +int gcd(int a, int b) { + while (b) { + int t = a % b; + a = b; + b = t; + } + return a; +} + +void triples_vanilla(int n) { + for (int c = 5, i = 0; 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 && gcd(a, b) == 1) { + printf("%d: {%d, %d, %d}\n", ++i, a, b, c); + if (--n == 0) goto done; + } + } + } + } + done:; +} + +struct triples { + int size, count; + int a, b, c; + int cco_state; +}; + +int triples_coro(struct triples* t) { + cco_routine(t) { + t->count = 0; + for (t->c = 5; t->size; ++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->count++ == t->size) + cco_return; + cco_yield(); + } + } + } + } + cco_cleanup: + puts("done"); + } + return 0; +} + +int main(void) +{ + puts("Vanilla triples:"); + triples_vanilla(5); + + puts("\nCoroutine triples:"); + struct triples t = {.size=INT32_MAX}; + int n = 0; + + while (triples_coro(&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/csmap_erase.c b/misc/examples/csmap_erase.c deleted file mode 100644 index 8d4eeae3..00000000 --- a/misc/examples/csmap_erase.c +++ /dev/null @@ -1,82 +0,0 @@ -// 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 -#include - -#define i_key int -#define i_val_str -#define i_type mymap -#include - -void printmap(mymap m) -{ - c_foreach (elem, mymap, m) - printf(" [%d, %s]", elem.ref->first, cstr_str(&elem.ref->second)); - printf("\nsize() == %" c_ZI "\n\n", mymap_size(&m)); -} - -int main(void) -{ - mymap m1 = {0}; - - // Fill in some data to test with, one at a time - mymap_insert(&m1, 1, cstr_lit("A")); - mymap_insert(&m1, 2, cstr_lit("B")); - mymap_insert(&m1, 3, cstr_lit("C")); - mymap_insert(&m1, 4, cstr_lit("D")); - mymap_insert(&m1, 5, cstr_lit("E")); - - puts("Starting data of map m1 is:"); - printmap(m1); - // The 1st member function removes an element at a given position - mymap_erase_at(&m1, mymap_advance(mymap_begin(&m1), 1)); - puts("After the 2nd element is deleted, the map m1 is:"); - printmap(m1); - - // Fill in some data to test with - mymap m2 = c_init(mymap, { - {10, "Bob"}, - {11, "Rob"}, - {12, "Robert"}, - {13, "Bert"}, - {14, "Bobby"}, - }); - - puts("Starting data of map m2 is:"); - printmap(m2); - mymap_iter it1 = mymap_advance(mymap_begin(&m2), 1); - mymap_iter it2 = mymap_find(&m2, mymap_back(&m2)->first); - - puts("to remove:"); - c_foreach (i, mymap, it1, it2) - printf(" [%d, %s]", i.ref->first, cstr_str(&i.ref->second)); - puts(""); - // The 2nd member function removes elements - // in the range [First, Last) - mymap_erase_range(&m2, it1, it2); - puts("After the middle elements are deleted, the map m2 is:"); - printmap(m2); - - mymap m3 = {0}; - - // Fill in some data to test with, one at a time, using emplace - mymap_emplace(&m3, 1, "red"); - mymap_emplace(&m3, 2, "yellow"); - mymap_emplace(&m3, 3, "blue"); - mymap_emplace(&m3, 4, "green"); - mymap_emplace(&m3, 5, "orange"); - mymap_emplace(&m3, 6, "purple"); - mymap_emplace(&m3, 7, "pink"); - - puts("Starting data of map m3 is:"); - printmap(m3); - // The 3rd member function removes elements with a given Key - int count = mymap_erase(&m3, 2); - // The 3rd member function also returns the number of elements removed - printf("The number of elements removed from m3 is: %d\n", count); - puts("After the element with a key of 2 is deleted, the map m3 is:"); - printmap(m3); - - c_drop(mymap, &m1, &m2, &m3); -} diff --git a/misc/examples/csmap_find.c b/misc/examples/csmap_find.c deleted file mode 100644 index c392338d..00000000 --- a/misc/examples/csmap_find.c +++ /dev/null @@ -1,73 +0,0 @@ -// 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 - -#define i_key int -#define i_val_str -#define i_tag istr -#include - -#define i_key csmap_istr_raw -#define i_tag istr -#include - -void print_elem(csmap_istr_raw p) { - printf("(%d, %s) ", p.first, p.second); -} - -#define using_print_collection(CX) \ - void print_collection_##CX(const CX* t) { \ - printf("%" c_ZI " elements: ", CX##_size(t)); \ - \ - c_foreach (p, CX, *t) { \ - print_elem(CX##_value_toraw(p.ref)); \ - } \ - puts(""); \ - } - -using_print_collection(csmap_istr) -using_print_collection(cvec_istr) - -void findit(csmap_istr c, csmap_istr_key val) -{ - printf("Trying find() on value %d\n", val); - csmap_istr_iter result = csmap_istr_find(&c, val); // prefer contains() or get() - if (result.ref) { - printf("Element found: "); print_elem(csmap_istr_value_toraw(result.ref)); puts(""); - } else { - puts("Element not found."); - } -} - -int main(void) -{ - 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, 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); - - c_foreach (i, cvec_istr, cvec_istr_begin(&v), cvec_istr_end(&v)) - csmap_istr_emplace(&m1, i.ref->first, i.ref->second); - - puts("The modified map m1 is (key, value):"); - print_collection_csmap_istr(&m1); - puts(""); - findit(m1, 45); - findit(m1, 6); - - csmap_istr_drop(&m1); - cvec_istr_drop(&v); -} diff --git a/misc/examples/csmap_insert.c b/misc/examples/csmap_insert.c deleted file mode 100644 index c9f02891..00000000 --- a/misc/examples/csmap_insert.c +++ /dev/null @@ -1,108 +0,0 @@ -// This implements the std::map insert c++ example at: -// https://docs.microsoft.com/en-us/cpp/standard-library/map-class?view=msvc-160#example-19 -#define i_key int -#define i_val int -#define i_tag ii // Map of int => int -#include - -#define i_implement -#include -#define i_key int -#define i_val_str -#define i_tag istr // Map of int => cstr -#include - -#define i_key csmap_ii_raw -#define i_opt c_no_cmp -#define i_tag ii -#include - -void print_ii(csmap_ii map) { - c_foreach (e, csmap_ii, map) - printf("(%d, %d) ", e.ref->first, e.ref->second); - puts(""); -} - -void print_istr(csmap_istr map) { - c_foreach (e, csmap_istr, map) - printf("(%d, %s) ", e.ref->first, cstr_str(&e.ref->second)); - puts(""); -} - -int main(void) -{ - // insert single values - csmap_ii m1 = {0}; - csmap_ii_insert(&m1, 1, 10); - csmap_ii_push(&m1, c_LITERAL(csmap_ii_value){2, 20}); - - puts("The original key and mapped values of m1 are:"); - print_ii(m1); - - // intentionally attempt a duplicate, single element - csmap_ii_result ret = csmap_ii_insert(&m1, 1, 111); - if (!ret.inserted) { - csmap_ii_value pr = *ret.ref; - puts("Insert failed, element with key value 1 already exists."); - printf(" The existing element is (%d, %d)\n", pr.first, pr.second); - } - else { - puts("The modified key and mapped values of m1 are:"); - print_ii(m1); - } - puts(""); - - csmap_ii_insert(&m1, 3, 30); - puts("The modified key and mapped values of m1 are:"); - print_ii(m1); - puts(""); - - // The templatized version inserting a jumbled range - csmap_ii m2 = {0}; - cvec_ii v = {0}; - typedef cvec_ii_value ipair; - 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) - printf("(%d, %d) ", e.ref->first, e.ref->second); - puts(""); - - c_foreach (e, cvec_ii, v) - csmap_ii_insert_or_assign(&m2, e.ref->first, e.ref->second); - - puts("The modified key and mapped values of m2 are:"); - c_foreach (e, csmap_ii, m2) - printf("(%d, %d) ", e.ref->first, e.ref->second); - puts("\n"); - - // The templatized versions move-constructing elements - csmap_istr m3 = {0}; - csmap_istr_value ip1 = {475, cstr_lit("blue")}, ip2 = {510, cstr_lit("green")}; - - // single element - csmap_istr_insert(&m3, ip1.first, cstr_move(&ip1.second)); - puts("After the first move insertion, m3 contains:"); - print_istr(m3); - - // single element - csmap_istr_insert(&m3, ip2.first, cstr_move(&ip2.second)); - puts("After the second move insertion, m3 contains:"); - print_istr(m3); - puts(""); - - csmap_ii m4 = {0}; - // Insert the elements from an initializer_list - 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(""); - - cvec_ii_drop(&v); - csmap_istr_drop(&m3); - c_drop(csmap_ii, &m1, &m2, &m4); -} diff --git a/misc/examples/csset_erase.c b/misc/examples/csset_erase.c deleted file mode 100644 index 9c7f5e1a..00000000 --- a/misc/examples/csset_erase.c +++ /dev/null @@ -1,41 +0,0 @@ -#include - -#define i_key int -#include - -int main(void) -{ - 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); - puts(""); - - int val = 64; - csset_int_iter it; - printf("Show values >= %d:\n", val); - it = csset_int_lower_bound(&set, val); - - c_foreach (k, csset_int, it, csset_int_end(&set)) - printf(" %d", *k.ref); - puts(""); - - printf("Erase values >= %d:\n", val); - while (it.ref) - it = csset_int_erase_at(&set, it); - - c_foreach (k, csset_int, set) - printf(" %d", *k.ref); - puts(""); - - val = 40; - printf("Erase values < %d:\n", val); - it = csset_int_lower_bound(&set, val); - csset_int_erase_range(&set, csset_int_begin(&set), it); - - c_foreach (k, csset_int, set) - printf(" %d", *k.ref); - puts(""); - - csset_int_drop(&set); -} diff --git a/misc/examples/cstr_match.c b/misc/examples/cstr_match.c deleted file mode 100644 index be03e981..00000000 --- a/misc/examples/cstr_match.c +++ /dev/null @@ -1,26 +0,0 @@ -#define i_implement -#include -#include -#include - -int main(void) -{ - cstr ss = cstr_lit("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 ? "" : cstr_str(&ss) + pos); - printf("equals: %d\n", cstr_equals(&ss, "The quick brown fox jumps over the lazy dog.JPG")); - printf("contains: %d\n", cstr_contains(&ss, "umps ove")); - printf("starts_with: %d\n", cstr_starts_with(&ss, "The quick brown")); - printf("ends_with: %d\n", cstr_ends_with(&ss, ".jpg")); - printf("ends_with: %d\n", cstr_ends_with(&ss, ".JPG")); - - cstr s1 = cstr_lit("hell😀 w😀rl🐨"); - csview ch1 = cstr_u8_chr(&s1, 7); - csview ch2 = cstr_u8_chr(&s1, 10); - printf("%s\nsize: %" c_ZI ", %" c_ZI "\n", cstr_str(&s1), cstr_u8_size(&s1), cstr_size(&s1)); - printf("ch1: %.*s\n", c_SV(ch1)); - printf("ch2: %.*s\n", c_SV(ch2)); - - c_drop(cstr, &ss, &s1); -} diff --git a/misc/examples/demos.c b/misc/examples/demos.c deleted file mode 100644 index 1a604d9f..00000000 --- a/misc/examples/demos.c +++ /dev/null @@ -1,194 +0,0 @@ -#define i_implement -#include - -void stringdemo1(void) -{ - cstr cs = cstr_lit("one-nine-three-seven-five"); - printf("%s.\n", cstr_str(&cs)); - - cstr_insert(&cs, 3, "-two"); - printf("%s.\n", cstr_str(&cs)); - - cstr_erase(&cs, 7, 5); // -nine - printf("%s.\n", cstr_str(&cs)); - - cstr_replace(&cs, "seven", "four", 1); - printf("%s.\n", cstr_str(&cs)); - - cstr_take(&cs, cstr_from_fmt("%s *** %s", cstr_str(&cs), cstr_str(&cs))); - printf("%s.\n", cstr_str(&cs)); - - printf("find \"four\": %s\n", cstr_str(&cs) + cstr_find(&cs, "four")); - - // reassign: - cstr_assign(&cs, "one two three four five six seven"); - cstr_append(&cs, " eight"); - printf("append: %s\n", cstr_str(&cs)); - - cstr_drop(&cs); -} - -#define i_key int64_t -#define i_tag ix -#include - -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]); - 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]); - } - - cvec_ix_drop(&bignums); -} - -#define i_key_str -#include - -void vectordemo2(void) -{ - cvec_str names = {0}; - cvec_str_emplace_back(&names, "Mary"); - cvec_str_emplace_back(&names, "Joe"); - cvec_str_emplace_back(&names, "Chris"); - cstr_assign(&names.data[1], "Jane"); // replace Joe - printf("names[1]: %s\n", cstr_str(&names.data[1])); - - cvec_str_sort(&names); // Sort the array - - c_foreach (i, cvec_str, names) - printf("sorted: %s\n", cstr_str(i.ref)); - - cvec_str_drop(&names); -} - -#define i_key int -#define i_tag ix -#define i_cmp_native -#include - -void listdemo1(void) -{ - clist_ix nums = {0}, nums2 = {0}; - for (int i = 0; i < 10; ++i) - clist_ix_push_back(&nums, i); - for (int i = 100; i < 110; ++i) - clist_ix_push_back(&nums2, i); - - /* splice nums2 to front of nums */ - clist_ix_splice(&nums, clist_ix_begin(&nums), &nums2); - c_foreach (i, clist_ix, nums) - printf("spliced: %d\n", *i.ref); - puts(""); - - *clist_ix_find(&nums, 104).ref += 50; - clist_ix_remove(&nums, 103); - clist_ix_iter it = clist_ix_begin(&nums); - clist_ix_erase_range(&nums, clist_ix_advance(it, 5), clist_ix_advance(it, 15)); - clist_ix_pop_front(&nums); - clist_ix_push_back(&nums, -99); - clist_ix_sort(&nums); - - c_foreach (i, clist_ix, nums) - printf("sorted: %d\n", *i.ref); - - c_drop(clist_ix, &nums, &nums2); -} - -#define i_key int -#define i_tag i -#include - -void setdemo1(void) -{ - cset_i nums = {0}; - cset_i_insert(&nums, 8); - cset_i_insert(&nums, 11); - - c_foreach (i, cset_i, nums) - printf("set: %d\n", *i.ref); - cset_i_drop(&nums); -} - -#define i_key int -#define i_val int -#define i_tag ii -#include - -void mapdemo1(void) -{ - cmap_ii nums = {0}; - cmap_ii_insert(&nums, 8, 64); - cmap_ii_insert(&nums, 11, 121); - printf("val 8: %d\n", *cmap_ii_at(&nums, 8)); - cmap_ii_drop(&nums); -} - -#define i_key_str -#define i_val int -#define i_tag si -#include - -void mapdemo2(void) -{ - cmap_si nums = {0}; - cmap_si_emplace_or_assign(&nums, "Hello", 64); - cmap_si_emplace_or_assign(&nums, "Groovy", 121); - cmap_si_emplace_or_assign(&nums, "Groovy", 200); // overwrite previous - - // iterate the map: - for (cmap_si_iter i = cmap_si_begin(&nums); i.ref; cmap_si_next(&i)) - printf("long: %s: %d\n", cstr_str(&i.ref->first), i.ref->second); - - // or rather use the short form: - c_foreach (i, cmap_si, nums) - printf("short: %s: %d\n", cstr_str(&i.ref->first), i.ref->second); - - cmap_si_drop(&nums); -} - -#define i_key_str -#define i_val_str -#include - -void mapdemo3(void) -{ - cmap_str table = {0}; - cmap_str_emplace(&table, "Map", "test"); - cmap_str_emplace(&table, "Make", "my"); - cmap_str_emplace(&table, "Sunny", "day"); - cmap_str_iter it = cmap_str_find(&table, "Make"); - c_foreach (i, cmap_str, table) - printf("entry: %s: %s\n", cstr_str(&i.ref->first), cstr_str(&i.ref->second)); - printf("size %" c_ZI ": remove: Make: %s\n", cmap_str_size(&table), cstr_str(&it.ref->second)); - //cmap_str_erase(&table, "Make"); - cmap_str_erase_at(&table, it); - - printf("size %" c_ZI "\n", cmap_str_size(&table)); - c_foreach (i, cmap_str, table) - printf("entry: %s: %s\n", cstr_str(&i.ref->first), cstr_str(&i.ref->second)); - - cmap_str_drop(&table); // frees key and value cstrs, and hash table. -} - -int main(void) -{ - printf("\nSTRINGDEMO1\n"); stringdemo1(); - printf("\nVECTORDEMO1\n"); vectordemo1(); - printf("\nVECTORDEMO2\n"); vectordemo2(); - printf("\nLISTDEMO1\n"); listdemo1(); - printf("\nSETDEMO1\n"); setdemo1(); - printf("\nMAPDEMO1\n"); mapdemo1(); - printf("\nMAPDEMO2\n"); mapdemo2(); - printf("\nMAPDEMO3\n"); mapdemo3(); -} diff --git a/misc/examples/dining_philosophers.c b/misc/examples/dining_philosophers.c deleted file mode 100644 index a5063a42..00000000 --- a/misc/examples/dining_philosophers.c +++ /dev/null @@ -1,105 +0,0 @@ -// https://en.wikipedia.org/wiki/Dining_philosophers_problem -#include -#include -#include -#include - -// 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_timer_await(&p->tm, duration); - - printf("Philosopher %d is hungry...\n", p->id); - cco_sem_await(p->left_fork); - cco_sem_await(p->right_fork); - - duration = 0.5 + crandf(); - printf("Philosopher %d is eating for %.0f minutes...\n", p->id, duration*10); - cco_timer_await(&p->tm, duration); - - cco_sem_release(p->left_fork); - cco_sem_release(p->right_fork); - } - - cco_cleanup: - 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_cleanup: - 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)); - - while (!cco_done(&dine)) { - if (cco_timer_expired(&tm)) - cco_stop(&dine); - dining(&dine); // resume - cco_sleep(0.001); - ++n; - } - printf("n=%d\n", n); -} diff --git a/misc/examples/forfilter.c b/misc/examples/forfilter.c deleted file mode 100644 index f3c008b3..00000000 --- a/misc/examples/forfilter.c +++ /dev/null @@ -1,149 +0,0 @@ -#include -#define i_import -#include -#define i_implement -#include -#include -#include - -#define i_type IVec -#define i_key int -#include - -// filters and transforms: -#define flt_skipValue(i, x) (*i.ref != (x)) -#define flt_isEven(i) ((*i.ref & 1) == 0) -#define flt_isOdd(i) (*i.ref & 1) -#define flt_square(i) (*i.ref * *i.ref) - -void demo1(void) -{ - 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)) - printf(" %d", *i.ref); - puts(""); - - int sum = 0; - c_forfilter (i, IVec, vec, - c_flt_skipwhile(i, *i.ref != 80) && - c_flt_skip(i, 1) && - flt_isEven(i) && - flt_skipValue(i, 80) && - c_flt_take(i, 5) // short-circuit - ){ - sum += flt_square(i); - } - - printf("\n sum: %d\n", sum); - IVec_drop(&vec); -} - - -/* Rust: -fn main() { - let vector = (1..) // Infinite range of integers - .skip_while(|x| *x != 11) // Skip initial numbers unequal 11 - .filter(|x| x % 2 != 0) // Collect odd numbers - .take(5) // Only take five numbers - .map(|x| x * x) // Square each number - .collect::>(); // Return as a new Vec - println!("{:?}", vector); // Print result -} -*/ -void demo2(void) -{ - IVec vector = {0}; - crange r = crange_make(INT64_MAX); - c_forfilter (x, crange, r, - c_flt_skipwhile(x, *x.ref != 11) && - (*x.ref % 2) != 0 && - c_flt_take(x, 5) - ){ - IVec_push(&vector, (int)(*x.ref * *x.ref)); - } - c_foreach (x, IVec, vector) printf(" %d", *x.ref); - - puts(""); - IVec_drop(&vector); -} - -/* Rust: -fn main() { - let sentence = "This is a sentence in Rust."; - let words: Vec<&str> = sentence - .split_whitespace() - .collect(); - let words_containing_i: Vec<&str> = words - .into_iter() - .filter(|word| word.contains("i")) - .collect(); - println!("{:?}", words_containing_i); -} -*/ -#define i_type SVec -#define i_keyclass csview -#include - -void demo3(void) -{ - const char* sentence = "This is a sentence in C99."; - SVec words = {0}; - c_fortoken (w, sentence, " ") // split words - SVec_push(&words, *w.ref); - - SVec words_containing_i = {0}; - c_forfilter (w, SVec, words, - csview_contains(*w.ref, "i")) - SVec_push(&words_containing_i, *w.ref); - - c_foreach (w, SVec, words_containing_i) - printf(" %.*s", c_SV(*w.ref)); - - puts(""); - c_drop(SVec, &words, &words_containing_i); -} - -void demo4(void) -{ - // Keep only uppercase letters and convert them to lowercase: - csview s = c_sv("ab123cReAghNGnΩoEp"); // Ω = multi-byte - cstr out = {0}; - - c_forfilter (i, csview, s, utf8_isupper(utf8_peek(i.ref))) { - char chr[4]; - utf8_encode(chr, utf8_tolower(utf8_peek(i.ref))); - cstr_push(&out, chr); - } - - printf(" %s\n", cstr_str(&out)); - cstr_drop(&out); -} - -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); - - c_forfilter (i, crange, R, - c_flt_skip(i,15) && - c_flt_skipwhile(i, flt_mid_decade(i)) && - c_flt_skip(i,30) && - flt_even(i) && - c_flt_take(i,5) - ){ - printf(" %lld", *i.ref); - } - puts(""); -} - -int main(void) -{ - puts("demo1"); demo1(); - puts("demo2"); demo2(); - puts("demo3"); demo3(); - puts("demo4"); demo4(); - puts("demo5"); demo5(); -} diff --git a/misc/examples/forloops.c b/misc/examples/forloops.c deleted file mode 100644 index 47cced8f..00000000 --- a/misc/examples/forloops.c +++ /dev/null @@ -1,69 +0,0 @@ -#include -#include - -#define i_type IVec -#define i_key int -#include - -#define i_type IMap -#define i_key int -#define i_val int -#include - - -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_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); -} diff --git a/misc/examples/functor.c b/misc/examples/functor.c deleted file mode 100644 index e3bde1dd..00000000 --- a/misc/examples/functor.c +++ /dev/null @@ -1,57 +0,0 @@ -// Implements c++ example: https://en.cppreference.com/w/cpp/container/priority_queue -// Example of per-instance less-function on a single priority queue type -// - -#include - -#define i_type IPQue -#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 - -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. - IPQue_ext copy = {q.less, IPQue_clone(q.get)}; - - for (printf("%s: \t", name); !IPQue_empty(©.get); IPQue_pop(©.get)) - printf("%d ", *IPQue_top(©.get)); - puts(""); - - IPQue_drop(©.get); -} - -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(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]); - puts(""); - - - // Max priority queue - IPQue_ext q1 = {.less=int_less}; - IPQue_put_n(&q1.get, data, n); - print_queue("q1", q1); - - // Min priority queue - IPQue_ext minq1 = {.less=int_greater}; - IPQue_put_n(&minq1.get, data, n); - print_queue("minq1", minq1); - - // 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/gauss2.c b/misc/examples/gauss2.c deleted file mode 100644 index 1ab8ade5..00000000 --- a/misc/examples/gauss2.c +++ /dev/null @@ -1,45 +0,0 @@ -#include -#include - -#define i_implement -#include -#include - -// Declare int -> int sorted map. -#define i_key int -#define i_val int -#include - -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.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); - - // 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)); - csmap_int_insert(&hist, index, 0).ref->second += 1; - } - - // Print the gaussian bar chart - c_forpair (index, count, csmap_int, hist) { - int n = (int)round((double)*_.count * StdDev * Scale * 2.5 / (double)N); - if (n > 0) { - cstr_resize(&bar, n, '*'); - printf("%4d %s\n", *_.index, cstr_str(&bar)); - } - } - cstr_drop(&bar); - csmap_int_drop(&hist); -} diff --git a/misc/examples/generator.c b/misc/examples/generator.c deleted file mode 100644 index a15f9ba5..00000000 --- a/misc/examples/generator.c +++ /dev/null @@ -1,55 +0,0 @@ -// https://quuxplusone.github.io/blog/2019/03/06/pythagorean-triples/ - -#include -#include - -typedef struct { - int size; - int a, b, c; -} Triple, Triple_value; - -typedef struct { - Triple_value* ref; - int count; - int cco_state; -} Triple_iter; - -int Triple_next(Triple_iter* it) { - Triple_value* g = it->ref; - cco_routine(it) - { - for (g->c = 5; g->size; ++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->size) - cco_return; - cco_yield(); - } - } - } - } - cco_cleanup: - it->ref = NULL; - } - return 0; -} - -Triple_iter Triple_begin(Triple* g) { - Triple_iter it = {.ref=g}; - Triple_next(&it); - return it; -} - - -int main(void) -{ - puts("Pythagorean triples with c < 100:"); - Triple triple = {.size=30}; // max number of triples - c_foreach (i, Triple, triple) { - if (i.ref->c < 100) - printf("%u: (%d, %d, %d)\n", i.count, i.ref->a, i.ref->b, i.ref->c); - else - cco_stop(&i); - } -} diff --git a/misc/examples/hashmap.c b/misc/examples/hashmap.c deleted file mode 100644 index cf11b7f7..00000000 --- a/misc/examples/hashmap.c +++ /dev/null @@ -1,50 +0,0 @@ -// https://doc.rust-lang.org/rust-by-example/std/hash.html -#define i_implement -#include -#define i_key_str -#define i_val_str -#include -#include - -const char* call(const char* number) { - if (!strcmp(number, "798-1364")) - return "We're sorry, the call cannot be completed as dialed." - " Please hang up and try again."; - else if (!strcmp(number, "645-7689")) - return "Hello, this is Mr. Awesome's Pizza. My name is Fred." - " What can I get for you today?"; - else - return "Hi! Who is this again?"; -} - -int main(void) { - cmap_str contacts = {0}; - - cmap_str_emplace(&contacts, "Daniel", "798-1364"); - cmap_str_emplace(&contacts, "Ashley", "645-7689"); - cmap_str_emplace(&contacts, "Katie", "435-8291"); - cmap_str_emplace(&contacts, "Robert", "956-1745"); - - const cmap_str_value* v; - if ((v = cmap_str_get(&contacts, "Daniel"))) - printf("Calling Daniel: %s\n", call(cstr_str(&v->second))); - else - printf("Don't have Daniel's number."); - - cmap_str_emplace_or_assign(&contacts, "Daniel", "164-6743"); - - if ((v = cmap_str_get(&contacts, "Ashley"))) - printf("Calling Ashley: %s\n", call(cstr_str(&v->second))); - else - printf("Don't have Ashley's number."); - - cmap_str_erase(&contacts, "Ashley"); - - puts(""); - c_forpair (contact, number, cmap_str, contacts) { - printf("Calling %s: %s\n", cstr_str(_.contact), call(cstr_str(_.number))); - } - puts(""); - - cmap_str_drop(&contacts); -} diff --git a/misc/examples/hashmaps/birthday.c b/misc/examples/hashmaps/birthday.c new file mode 100644 index 00000000..4742cb45 --- /dev/null +++ b/misc/examples/hashmaps/birthday.c @@ -0,0 +1,68 @@ +#include +#include +#include +#include + +#define i_tag ic +#define i_key uint64_t +#define i_val int +#include + +static uint64_t seed = 12345; + +static void test_repeats(void) +{ + enum {BITS = 46, BITS_TEST = BITS/2 + 2}; + 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); + + cmap_ic m = cmap_ic_with_capacity(N); + c_forrange (i, N) { + uint64_t k = crand_u64(&rng) & mask; + int v = cmap_ic_insert(&m, k, 0).ref->second += 1; + if (v > 1) printf("repeated value %" PRIu64 " (%d) at 2^%d\n", + k, v, (int)log2((double)i)); + } + cmap_ic_drop(&m); +} + +#define i_key uint32_t +#define i_val uint64_t +#define i_tag x +#include + +void test_distribution(void) +{ + enum {BITS = 26}; + printf("distribution test: 2^%d values\n", BITS); + crand_t rng = crand_init(seed); + const size_t N = 1ull << BITS ; + + cmap_x map = {0}; + c_forrange (N) { + uint64_t k = crand_u64(&rng); + cmap_x_insert(&map, k & 0xf, 0).ref->second += 1; + } + + uint64_t sum = 0; + c_foreach (i, cmap_x, map) sum += i.ref->second; + sum /= (uint64_t)map.size; + + c_foreach (i, cmap_x, map) { + printf("%4" PRIu32 ": %" PRIu64 " - %" PRIu64 ": %11.8f\n", + i.ref->first, i.ref->second, sum, + (1.0 - (double)i.ref->second / (double)sum)); + } + + cmap_x_drop(&map); +} + +int main(void) +{ + seed = (uint64_t)time(NULL); + test_distribution(); + test_repeats(); +} diff --git a/misc/examples/hashmaps/books.c b/misc/examples/hashmaps/books.c new file mode 100644 index 00000000..1fd57f27 --- /dev/null +++ b/misc/examples/hashmaps/books.c @@ -0,0 +1,62 @@ +// https://doc.rust-lang.org/std/collections/struct.HashMap.html +#define i_implement +#include +#define i_key_str +#define i_val_str +#include + +// Type inference lets us omit an explicit type signature (which +// would be `HashMap` in this example). +int main(void) +{ + cmap_str book_reviews = {0}; + + // Review some books. + cmap_str_emplace(&book_reviews, + "Adventures of Huckleberry Finn", + "My favorite book." + ); + cmap_str_emplace(&book_reviews, + "Grimms' Fairy Tales", + "Masterpiece." + ); + cmap_str_emplace(&book_reviews, + "Pride and Prejudice", + "Very enjoyable" + ); + cmap_str_insert(&book_reviews, + cstr_lit("The Adventures of Sherlock Holmes"), + cstr_lit("Eye lyked it alot.") + ); + + // Check for a specific one. + // When collections store owned values (String), they can still be + // queried using references (&str). + if (cmap_str_contains(&book_reviews, "Les Misérables")) { + printf("We've got %" c_ZI " reviews, but Les Misérables ain't one.", + cmap_str_size(&book_reviews)); + } + + // oops, this review has a lot of spelling mistakes, let's delete it. + cmap_str_erase(&book_reviews, "The Adventures of Sherlock Holmes"); + + // Look up the values associated with some keys. + const char* to_find[] = {"Pride and Prejudice", "Alice's Adventure in Wonderland"}; + c_forrange (i, c_arraylen(to_find)) { + const cmap_str_value* b = cmap_str_get(&book_reviews, to_find[i]); + if (b) + printf("%s: %s\n", cstr_str(&b->first), cstr_str(&b->second)); + else + printf("%s is unreviewed.\n", to_find[i]); + } + + // Look up the value for a key (will panic if the key is not found). + printf("Review for Jane: %s\n", cstr_str(cmap_str_at(&book_reviews, "Pride and Prejudice"))); + + // Iterate over everything. + c_forpair (book, review, cmap_str, book_reviews) { + printf("%s: \"%s\"\n", cstr_str(_.book), cstr_str(_.review)); + } + + cmap_str_drop(&book_reviews); +} diff --git a/misc/examples/hashmaps/hashmap.c b/misc/examples/hashmaps/hashmap.c new file mode 100644 index 00000000..cf11b7f7 --- /dev/null +++ b/misc/examples/hashmaps/hashmap.c @@ -0,0 +1,50 @@ +// https://doc.rust-lang.org/rust-by-example/std/hash.html +#define i_implement +#include +#define i_key_str +#define i_val_str +#include +#include + +const char* call(const char* number) { + if (!strcmp(number, "798-1364")) + return "We're sorry, the call cannot be completed as dialed." + " Please hang up and try again."; + else if (!strcmp(number, "645-7689")) + return "Hello, this is Mr. Awesome's Pizza. My name is Fred." + " What can I get for you today?"; + else + return "Hi! Who is this again?"; +} + +int main(void) { + cmap_str contacts = {0}; + + cmap_str_emplace(&contacts, "Daniel", "798-1364"); + cmap_str_emplace(&contacts, "Ashley", "645-7689"); + cmap_str_emplace(&contacts, "Katie", "435-8291"); + cmap_str_emplace(&contacts, "Robert", "956-1745"); + + const cmap_str_value* v; + if ((v = cmap_str_get(&contacts, "Daniel"))) + printf("Calling Daniel: %s\n", call(cstr_str(&v->second))); + else + printf("Don't have Daniel's number."); + + cmap_str_emplace_or_assign(&contacts, "Daniel", "164-6743"); + + if ((v = cmap_str_get(&contacts, "Ashley"))) + printf("Calling Ashley: %s\n", call(cstr_str(&v->second))); + else + printf("Don't have Ashley's number."); + + cmap_str_erase(&contacts, "Ashley"); + + puts(""); + c_forpair (contact, number, cmap_str, contacts) { + printf("Calling %s: %s\n", cstr_str(_.contact), call(cstr_str(_.number))); + } + puts(""); + + cmap_str_drop(&contacts); +} diff --git a/misc/examples/hashmaps/new_map.c b/misc/examples/hashmaps/new_map.c new file mode 100644 index 00000000..de990040 --- /dev/null +++ b/misc/examples/hashmaps/new_map.c @@ -0,0 +1,75 @@ +#define i_implement +#include +#include + +forward_cmap(cmap_pnt, struct Point, int); + +typedef struct MyStruct { + cmap_pnt pntmap; + cstr name; +} MyStruct; + +// int => int map +#define i_key int +#define i_val int +#include + +// Point => int map +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; +} + +// Point => int map +#define i_key Point +#define i_val int +#define i_cmp point_cmp +#define i_hash c_default_hash +#define i_is_forward +#define i_tag pnt +#include + +// cstr => cstr map +#define i_key_str +#define i_val_str +#include + +// string set +#define i_key_str +#include + + +int main(void) +{ + 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_init(cmap_str, { + {"Hello, friend", "long time no see"}, + {"So long", "see you around"}, + }); + + cset_str sset = c_init(cset_str, { + "Hello, friend", + "Nice to see you again", + "So long", + }); + + cmap_int map = {0}; + cmap_int_insert(&map, 123, 321); + cmap_int_insert(&map, 456, 654); + cmap_int_insert(&map, 789, 987); + + c_foreach (i, cset_str, sset) + printf(" %s\n", cstr_str(i.ref)); + + cmap_int_drop(&map); + cset_str_drop(&sset); + cmap_str_drop(&smap); + cmap_pnt_drop(&pmap); +} diff --git a/misc/examples/hashmaps/phonebook.c b/misc/examples/hashmaps/phonebook.c new file mode 100644 index 00000000..faf7566e --- /dev/null +++ b/misc/examples/hashmaps/phonebook.c @@ -0,0 +1,72 @@ +// The MIT License (MIT) +// Copyright (c) 2018 Maksim Andrianov +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +// Program to emulates the phone book. +#define i_implement +#include + +#define i_key_str +#define i_val_str +#include + +#define i_key_str +#include + +void print_phone_book(cmap_str phone_book) +{ + c_foreach (i, cmap_str, phone_book) + printf("%s\t- %s\n", cstr_str(&i.ref->first), cstr_str(&i.ref->second)); +} + +int main(int argc, char **argv) +{ + cmap_str phone_book = c_init(cmap_str, { + {"Lilia Friedman", "(892) 670-4739"}, + {"Tariq Beltran", "(489) 600-7575"}, + {"Laiba Juarez", "(303) 885-5692"}, + {"Elliott Mooney", "(945) 616-4482"}, + }); + + printf("Phone book:\n"); + print_phone_book(phone_book); + + cmap_str_emplace(&phone_book, "Zak Byers", "(551) 396-1880"); + cmap_str_emplace(&phone_book, "Zak Byers", "(551) 396-1990"); + + printf("\nPhone book after adding Zak Byers:\n"); + print_phone_book(phone_book); + + if (cmap_str_contains(&phone_book, "Tariq Beltran")) + printf("\nTariq Beltran is in phone book\n"); + + cmap_str_erase(&phone_book, "Tariq Beltran"); + cmap_str_erase(&phone_book, "Elliott Mooney"); + + printf("\nPhone book after erasing Tariq and Elliott:\n"); + print_phone_book(phone_book); + + cmap_str_emplace_or_assign(&phone_book, "Zak Byers", "(555) 396-188"); + + printf("\nPhone book after update phone of Zak Byers:\n"); + print_phone_book(phone_book); + + cmap_str_drop(&phone_book); +} diff --git a/misc/examples/hashmaps/unordered_set.c b/misc/examples/hashmaps/unordered_set.c new file mode 100644 index 00000000..dd899d78 --- /dev/null +++ b/misc/examples/hashmaps/unordered_set.c @@ -0,0 +1,45 @@ +// https://iq.opengenus.org/containers-cpp-stl/ +// C program to demonstrate various function of stc cset +#define i_implement +#include +#define i_key_str +#include + +int main(void) +{ + // declaring set for storing string data-type + cset_str stringSet = {0}; + c_defer( + cset_str_drop(&stringSet) + ){ + // inserting various string, same string will be stored + // once in set + cset_str_emplace(&stringSet, "code"); + cset_str_emplace(&stringSet, "in"); + cset_str_emplace(&stringSet, "C"); + cset_str_emplace(&stringSet, "is"); + cset_str_emplace(&stringSet, "fast"); + + const char* key = "slow"; + + // find returns end iterator if key is not found, + // else it returns iterator to that key + + if (cset_str_find(&stringSet, key).ref == NULL) + printf("\"%s\" not found\n", key); + else + printf("Found \"%s\"\n", key); + + key = "C"; + if (!cset_str_contains(&stringSet, key)) + printf("\"%s\" not found\n", key); + else + printf("Found \"%s\"\n", key); + + // now iterating over whole set and printing its + // content + printf("All elements :\n"); + c_foreach (itr, cset_str, stringSet) + printf("%s\n", cstr_str(itr.ref)); + } +} diff --git a/misc/examples/hashmaps/vikings.c b/misc/examples/hashmaps/vikings.c new file mode 100644 index 00000000..d6125854 --- /dev/null +++ b/misc/examples/hashmaps/vikings.c @@ -0,0 +1,59 @@ +#define i_implement +#include + +typedef struct Viking { + cstr name; + cstr country; +} Viking; + +void Viking_drop(Viking* vk) { + cstr_drop(&vk->name); + cstr_drop(&vk->country); +} + +// Define Viking lookup struct with hash, cmp, and convertion functions between Viking and RViking structs: + +typedef struct RViking { + const char* name; + const char* country; +} RViking; + +static inline int RViking_cmp(const RViking* rx, const RViking* ry) { + int c = strcmp(rx->name, ry->name); + return c ? c : strcmp(rx->country, ry->country); +} + +static inline Viking Viking_from(RViking raw) { // note: parameter is by value + return c_LITERAL(Viking){cstr_from(raw.name), cstr_from(raw.country)}; +} + +static inline RViking Viking_toraw(const Viking* vp) { + return c_LITERAL(RViking){cstr_str(&vp->name), cstr_str(&vp->country)}; +} + +// With this in place, we define the Viking => int hash map type: +#define i_type Vikings +#define i_keyclass Viking // key type +#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_val int // mapped type +#include + +int main(void) +{ + Vikings vikings = {0}; + 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, c_LITERAL(RViking){"Einar", "Norway"}); + v->second += 3; // add 3 hp points to Einar + + c_forpair (vk, hp, Vikings, vikings) { + printf("%s of %s has %d hp\n", cstr_str(&_.vk->name), cstr_str(&_.vk->country), *_.hp); + } + Vikings_drop(&vikings); +} diff --git a/misc/examples/inits.c b/misc/examples/inits.c deleted file mode 100644 index 53a49f1f..00000000 --- a/misc/examples/inits.c +++ /dev/null @@ -1,108 +0,0 @@ -#define i_implement -#include - -#define i_key int -#define i_val_str -#define i_tag id // Map of int => cstr -#include - -#define i_key_str -#define i_val int -#define i_tag cnt // Map of cstr => int -#include - -typedef struct {int x, y;} ipair_t; -inline static int ipair_cmp(const ipair_t* a, const ipair_t* b) { - int c = c_default_cmp(&a->x, &b->x); - return c ? c : c_default_cmp(&a->y, &b->y); -} - - -#define i_key ipair_t -#define i_cmp ipair_cmp -#define i_tag ip -#include - -#define i_key ipair_t -#define i_cmp ipair_cmp -#define i_tag ip -#include - -#define i_key float -#define i_tag f -#include - -int main(void) -{ - // CVEC FLOAT / PRIORITY QUEUE - - cpque_f floats = {0}; - const float nums[] = {4.0f, 2.0f, 5.0f, 3.0f, 1.0f}; - - // PRIORITY QUEUE - c_forrange (i, c_arraylen(nums)) - cpque_f_push(&floats, nums[i]); - - puts("\npop and show high priorites first:"); - while (! cpque_f_empty(&floats)) { - printf("%.1f ", (double)*cpque_f_top(&floats)); - cpque_f_pop(&floats); - } - puts("\n"); - cpque_f_drop(&floats); - - // CMAP ID - - int year = 2020; - cmap_id idnames = {0}; - cmap_id_emplace(&idnames, 100, "Hello"); - cmap_id_insert(&idnames, 110, cstr_lit("World")); - cmap_id_insert(&idnames, 120, cstr_from_fmt("Howdy, -%d-", year)); - - c_foreach (i, cmap_id, idnames) - printf("%d: %s\n", i.ref->first, cstr_str(&i.ref->second)); - puts(""); - cmap_id_drop(&idnames); - - // CMAP CNT - - cmap_cnt countries = c_init(cmap_cnt, { - {"Norway", 100}, - {"Denmark", 50}, - {"Iceland", 10}, - {"Belgium", 10}, - {"Italy", 10}, - {"Germany", 10}, - {"Spain", 10}, - {"France", 10}, - }); - cmap_cnt_emplace(&countries, "Greenland", 0).ref->second += 20; - cmap_cnt_emplace(&countries, "Sweden", 0).ref->second += 20; - cmap_cnt_emplace(&countries, "Norway", 0).ref->second += 20; - cmap_cnt_emplace(&countries, "Finland", 0).ref->second += 20; - - c_forpair (country, health, cmap_cnt, countries) - printf("%s: %d\n", cstr_str(_.country), *_.health); - puts(""); - cmap_cnt_drop(&countries); - - // CVEC PAIR - - 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) - printf("(%d %d) ", i.ref->x, i.ref->y); - puts(""); - cvec_ip_drop(&pairs1); - - // CLIST PAIR - - 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) - printf("(%d %d) ", i.ref->x, i.ref->y); - puts(""); - clist_ip_drop(&pairs2); -} diff --git a/misc/examples/intrusive.c b/misc/examples/intrusive.c deleted file mode 100644 index c22ed260..00000000 --- a/misc/examples/intrusive.c +++ /dev/null @@ -1,33 +0,0 @@ -// Example of clist using the node API. - -#include - -#define i_type List -#define i_key int -#define i_cmp_native -#include - -void printList(List list) { - printf("list:"); - c_foreach (i, List, list) - printf(" %d", *i.ref); - puts(""); -} - -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})); - - printList(list); - - puts("Sort list"); - List_sort(&list); - printList(list); - - puts("Remove nodes from list"); - while (!List_empty(&list)) - c_free(List_unlink_after_node(&list, list.last)); - - printList(list); -} diff --git a/misc/examples/linkedlists/intrusive.c b/misc/examples/linkedlists/intrusive.c new file mode 100644 index 00000000..c22ed260 --- /dev/null +++ b/misc/examples/linkedlists/intrusive.c @@ -0,0 +1,33 @@ +// Example of clist using the node API. + +#include + +#define i_type List +#define i_key int +#define i_cmp_native +#include + +void printList(List list) { + printf("list:"); + c_foreach (i, List, list) + printf(" %d", *i.ref); + puts(""); +} + +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})); + + printList(list); + + puts("Sort list"); + List_sort(&list); + printList(list); + + puts("Remove nodes from list"); + while (!List_empty(&list)) + c_free(List_unlink_after_node(&list, list.last)); + + printList(list); +} diff --git a/misc/examples/linkedlists/list.c b/misc/examples/linkedlists/list.c new file mode 100644 index 00000000..ad8bebb8 --- /dev/null +++ b/misc/examples/linkedlists/list.c @@ -0,0 +1,64 @@ +#include +#include +#include +#include + +#define i_type DList +#define i_key double +#define i_cmp_native +#include + +int main(void) { + const int n = 3000000; + DList list = {0}; + + crand_t rng = crand_init(1234567); + int m = 0; + c_forrange (n) + DList_push_back(&list, crand_f64(&rng)*n + 100), ++m; + + double sum = 0.0; + printf("sumarize %d:\n", m); + c_foreach (i, DList, list) + sum += *i.ref; + printf("sum %f\n\n", sum); + + c_forfilter (i, DList, list, c_flt_take(i, 10)) + printf("%8d: %10f\n", c_flt_getcount(i), *i.ref); + + puts("sort"); + DList_sort(&list); // qsort O(n*log n) + puts("sorted"); + + c_forfilter (i, DList, list, c_flt_take(i, 10)) + printf("%8d: %10f\n", c_flt_getcount(i), *i.ref); + puts(""); + + DList_drop(&list); + list = c_init(DList, {10, 20, 30, 40, 30, 50}); + + const double* v = DList_get(&list, 30); + printf("found: %f\n", *v); + + c_foreach (i, DList, list) + printf(" %g", *i.ref); + puts(""); + + DList_remove(&list, 30); + DList_insert_at(&list, DList_begin(&list), 5); // same as push_front() + DList_push_back(&list, 500); + DList_push_front(&list, 1964); + + printf("Full: "); + c_foreach (i, DList, list) + printf(" %g", *i.ref); + + printf("\nSubs: "); + DList_iter it = DList_begin(&list); + + c_foreach (i, DList, DList_advance(it, 4), DList_end(&list)) + printf(" %g", *i.ref); + puts(""); + + DList_drop(&list); +} diff --git a/misc/examples/linkedlists/list_erase.c b/misc/examples/linkedlists/list_erase.c new file mode 100644 index 00000000..211c5a5d --- /dev/null +++ b/misc/examples/linkedlists/list_erase.c @@ -0,0 +1,30 @@ +// erasing from clist +#include + +#define i_type IList +#define i_key int +#include + +int main(void) +{ + IList L = c_init(IList, {10, 20, 30, 40, 50}); + + c_foreach (x, IList, L) + printf("%d ", *x.ref); + puts(""); + // 10 20 30 40 50 + IList_iter it = IList_begin(&L); // ^ + IList_next(&it); + it = IList_erase_at(&L, it); // 10 30 40 50 + // ^ + IList_iter end = IList_end(&L); // + IList_next(&it); + it = IList_erase_range(&L, it, end); // 10 30 + // ^ + printf("list contains:"); + c_foreach (x, IList, L) + printf(" %d", *x.ref); + puts(""); + + IList_drop(&L); +} diff --git a/misc/examples/linkedlists/list_splice.c b/misc/examples/linkedlists/list_splice.c new file mode 100644 index 00000000..f1fd6e1f --- /dev/null +++ b/misc/examples/linkedlists/list_splice.c @@ -0,0 +1,38 @@ +#include + +#define i_key int +#define i_tag i +#include + +void print_ilist(const char* s, clist_i list) +{ + printf("%s", s); + c_foreach (i, clist_i, list) { + printf(" %d", *i.ref); + } + puts(""); +} + +int main(void) +{ + 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); + + clist_i_iter it = clist_i_advance(clist_i_begin(&list1), 2); + it = clist_i_splice(&list1, it, &list2); + + puts("After splice"); + print_ilist("list1:", list1); + print_ilist("list2:", list2); + + clist_i_splice_range(&list2, clist_i_begin(&list2), &list1, it, clist_i_end(&list1)); + + puts("After splice_range"); + print_ilist("list1:", list1); + print_ilist("list2:", list2); + + c_drop(clist_i, &list1, &list2); +} diff --git a/misc/examples/linkedlists/new_list.c b/misc/examples/linkedlists/new_list.c new file mode 100644 index 00000000..2112bf1f --- /dev/null +++ b/misc/examples/linkedlists/new_list.c @@ -0,0 +1,70 @@ +#include +#include + +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 + +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 + +#define i_key float +#define i_cmp_native // use < and == operators for comparison +#include + +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 + +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/list.c b/misc/examples/list.c deleted file mode 100644 index ad8bebb8..00000000 --- a/misc/examples/list.c +++ /dev/null @@ -1,64 +0,0 @@ -#include -#include -#include -#include - -#define i_type DList -#define i_key double -#define i_cmp_native -#include - -int main(void) { - const int n = 3000000; - DList list = {0}; - - crand_t rng = crand_init(1234567); - int m = 0; - c_forrange (n) - DList_push_back(&list, crand_f64(&rng)*n + 100), ++m; - - double sum = 0.0; - printf("sumarize %d:\n", m); - c_foreach (i, DList, list) - sum += *i.ref; - printf("sum %f\n\n", sum); - - c_forfilter (i, DList, list, c_flt_take(i, 10)) - printf("%8d: %10f\n", c_flt_getcount(i), *i.ref); - - puts("sort"); - DList_sort(&list); // qsort O(n*log n) - puts("sorted"); - - c_forfilter (i, DList, list, c_flt_take(i, 10)) - printf("%8d: %10f\n", c_flt_getcount(i), *i.ref); - puts(""); - - DList_drop(&list); - list = c_init(DList, {10, 20, 30, 40, 30, 50}); - - const double* v = DList_get(&list, 30); - printf("found: %f\n", *v); - - c_foreach (i, DList, list) - printf(" %g", *i.ref); - puts(""); - - DList_remove(&list, 30); - DList_insert_at(&list, DList_begin(&list), 5); // same as push_front() - DList_push_back(&list, 500); - DList_push_front(&list, 1964); - - printf("Full: "); - c_foreach (i, DList, list) - printf(" %g", *i.ref); - - printf("\nSubs: "); - DList_iter it = DList_begin(&list); - - c_foreach (i, DList, DList_advance(it, 4), DList_end(&list)) - printf(" %g", *i.ref); - puts(""); - - DList_drop(&list); -} diff --git a/misc/examples/list_erase.c b/misc/examples/list_erase.c deleted file mode 100644 index 211c5a5d..00000000 --- a/misc/examples/list_erase.c +++ /dev/null @@ -1,30 +0,0 @@ -// erasing from clist -#include - -#define i_type IList -#define i_key int -#include - -int main(void) -{ - IList L = c_init(IList, {10, 20, 30, 40, 50}); - - c_foreach (x, IList, L) - printf("%d ", *x.ref); - puts(""); - // 10 20 30 40 50 - IList_iter it = IList_begin(&L); // ^ - IList_next(&it); - it = IList_erase_at(&L, it); // 10 30 40 50 - // ^ - IList_iter end = IList_end(&L); // - IList_next(&it); - it = IList_erase_range(&L, it, end); // 10 30 - // ^ - printf("list contains:"); - c_foreach (x, IList, L) - printf(" %d", *x.ref); - puts(""); - - IList_drop(&L); -} diff --git a/misc/examples/list_splice.c b/misc/examples/list_splice.c deleted file mode 100644 index f1fd6e1f..00000000 --- a/misc/examples/list_splice.c +++ /dev/null @@ -1,38 +0,0 @@ -#include - -#define i_key int -#define i_tag i -#include - -void print_ilist(const char* s, clist_i list) -{ - printf("%s", s); - c_foreach (i, clist_i, list) { - printf(" %d", *i.ref); - } - puts(""); -} - -int main(void) -{ - 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); - - clist_i_iter it = clist_i_advance(clist_i_begin(&list1), 2); - it = clist_i_splice(&list1, it, &list2); - - puts("After splice"); - print_ilist("list1:", list1); - print_ilist("list2:", list2); - - clist_i_splice_range(&list2, clist_i_begin(&list2), &list1, it, clist_i_end(&list1)); - - puts("After splice_range"); - print_ilist("list1:", list1); - print_ilist("list2:", list2); - - c_drop(clist_i, &list1, &list2); -} diff --git a/misc/examples/lower_bound.c b/misc/examples/lower_bound.c deleted file mode 100644 index bea828f2..00000000 --- a/misc/examples/lower_bound.c +++ /dev/null @@ -1,66 +0,0 @@ -#include - -#define i_key int -#define i_cmp_native -#include - -#define i_key int -#include - -int main(void) -{ - // TEST SORTED VECTOR - { - int key, *res; - cvec_int vec = c_init(cvec_int, {40, 600, 1, 7000, 2, 500, 30}); - - cvec_int_sort(&vec); - - key = 100; - res = cvec_int_lower_bound(&vec, key).ref; - if (res) - printf("Sorted Vec %d: lower bound: %d\n", key, *res); // 500 - - key = 10; - cvec_int_iter it1 = cvec_int_lower_bound(&vec, key); - if (it1.ref) - printf("Sorted Vec %3d: lower_bound: %d\n", key, *it1.ref); // 30 - - key = 600; - cvec_int_iter it2 = cvec_int_binary_search(&vec, key); - if (it2.ref) - printf("Sorted Vec %d: bin. search: %d\n", key, *it2.ref); // 600 - - c_foreach (i, cvec_int, it1, it2) - printf(" %d\n", *i.ref); - - puts(""); - cvec_int_drop(&vec); - } - - // TEST SORTED SET - { - int key, *res; - csset_int set = c_init(csset_int, {40, 600, 1, 7000, 2, 500, 30}); - - key = 100; - res = csset_int_lower_bound(&set, key).ref; - if (res) - printf("Sorted Set %d: lower bound: %d\n", key, *res); // 500 - - key = 10; - csset_int_iter it1 = csset_int_lower_bound(&set, key); - if (it1.ref) - printf("Sorted Set %3d: lower bound: %d\n", key, *it1.ref); // 30 - - key = 600; - csset_int_iter it2 = csset_int_find(&set, key); - if (it2.ref) - printf("Sorted Set %d: find : %d\n", key, *it2.ref); // 600 - - c_foreach (i, csset_int, it1, it2) - printf(" %d\n", *i.ref); - - csset_int_drop(&set); - } -} diff --git a/misc/examples/make.sh b/misc/examples/make.sh index cf224950..7135ffdf 100755 --- a/misc/examples/make.sh +++ b/misc/examples/make.sh @@ -37,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/mapmap.c b/misc/examples/mapmap.c deleted file mode 100644 index d3065659..00000000 --- a/misc/examples/mapmap.c +++ /dev/null @@ -1,64 +0,0 @@ -// create a structure like: std::map>: -#define i_implement -#include - -// People: std::map -#define i_type People -#define i_key_str // name -#define i_val_str // email -#define i_keydrop(p) (printf("kdrop: %s\n", cstr_str(p)), cstr_drop(p)) // override -#include - -// Departments: std::map -#define i_type Departments -#define i_key_str // dep. name -#define i_valclass People -#include - - -void add(Departments* deps, const char* name, const char* email, const char* dep) -{ - People *people = &Departments_emplace(deps, dep, People_init()).ref->second; - People_emplace_or_assign(people, name, email); -} - -int contains(Departments* map, const char* name) -{ - int count = 0; - c_foreach (i, Departments, *map) - if (People_contains(&i.ref->second, name)) - ++count; - return count; -} - -int main(void) -{ - Departments map = {0}; - - add(&map, "Anna Kendro", "Anna@myplace.com", "Support"); - add(&map, "Terry Dane", "Terry@myplace.com", "Development"); - add(&map, "Kik Winston", "Kik@myplace.com", "Finance"); - add(&map, "Nancy Drew", "Nancy@live.com", "Development"); - add(&map, "Nick Denton", "Nick@myplace.com", "Finance"); - add(&map, "Stan Whiteword", "Stan@myplace.com", "Marketing"); - add(&map, "Serena Bath", "Serena@myplace.com", "Support"); - add(&map, "Patrick Dust", "Patrick@myplace.com", "Finance"); - add(&map, "Red Winger", "Red@gmail.com", "Marketing"); - add(&map, "Nick Denton", "Nick@yahoo.com", "Support"); - add(&map, "Colin Turth", "Colin@myplace.com", "Support"); - add(&map, "Dennis Kay", "Dennis@mail.com", "Marketing"); - add(&map, "Anne Dickens", "Anne@myplace.com", "Development"); - - c_foreach (i, Departments, map) - c_forpair (name, email, People, i.ref->second) - printf("%s: %s - %s\n", cstr_str(&i.ref->first), cstr_str(_.name), cstr_str(_.email)); - puts(""); - - printf("found Nick Denton: %d\n", contains(&map, "Nick Denton")); - printf("found Patrick Dust: %d\n", contains(&map, "Patrick Dust")); - printf("found Dennis Kay: %d\n", contains(&map, "Dennis Kay")); - printf("found Serena Bath: %d\n", contains(&map, "Serena Bath")); - puts("Done"); - - Departments_drop(&map); -} diff --git a/misc/examples/mixed/astar.c b/misc/examples/mixed/astar.c new file mode 100644 index 00000000..590b7952 --- /dev/null +++ b/misc/examples/mixed/astar.c @@ -0,0 +1,174 @@ +// +// -- An A* pathfinder inspired by the excellent tutorial at Red Blob Games -- +// +// 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 +#include + +typedef struct +{ + int x; + int y; + int priorty; + int width; +} +point; + +point +point_init(int x, int y, int width) +{ + return c_LITERAL(point){ x, y, 0, width }; +} + +int +point_cmp_priority(const point* a, const point* b) +{ + return c_default_cmp(&a->priorty, &b->priorty); +} + +int +point_equal(const point* a, const point* b) +{ + return a->x == b->x && a->y == b->y; +} + +point +point_from(const cstr* maze, const char* c, int width) +{ + int index = (int)cstr_find(maze, c); + return point_init(index % width, index / width, width); +} + +int +point_index(const point* p) +{ + return p->x + p->width * p->y; +} + +int +point_key_cmp(const point* a, const point* b) +{ + int i = point_index(a); + int j = point_index(b); + return (i == j) ? 0 : (i < j) ? -1 : 1; +} + +#define i_key point +#define i_cmp point_cmp_priority +#include + +#define i_key point +#define i_opt c_no_cmp +#include + +#define i_key point +#define i_val int +#define i_cmp point_key_cmp +#define i_tag pcost +#include + +#define i_key point +#define i_val point +#define i_cmp point_key_cmp +#define i_tag pstep +#include + +cdeq_point +astar(cstr* maze, int width) +{ + cdeq_point ret_path = {0}; + + cpque_point front = {0}; + csmap_pstep from = {0}; + csmap_pcost costs = {0}; + c_defer( + cpque_point_drop(&front), + csmap_pstep_drop(&from), + csmap_pcost_drop(&costs) + ){ + point start = point_from(maze, "@", width); + point goal = point_from(maze, "!", width); + csmap_pcost_insert(&costs, start, 0); + cpque_point_push(&front, start); + while (!cpque_point_empty(&front)) + { + point current = *cpque_point_top(&front); + cpque_point_pop(&front); + if (point_equal(¤t, &goal)) + break; + point deltas[] = { + { -1, +1, 0, width }, { 0, +1, 0, width }, { 1, +1, 0, width }, + { -1, 0, 0, width }, /* ~ ~ ~ ~ ~ ~ ~ */ { 1, 0, 0, width }, + { -1, -1, 0, width }, { 0, -1, 0, width }, { 1, -1, 0, width }, + }; + for (size_t i = 0; i < c_arraylen(deltas); i++) + { + point delta = deltas[i]; + point next = point_init(current.x + delta.x, current.y + delta.y, width); + int new_cost = *csmap_pcost_at(&costs, current); + if (cstr_str(maze)[point_index(&next)] != '#') + { + const csmap_pcost_value *cost = csmap_pcost_get(&costs, next); + if (cost == NULL || new_cost < cost->second) + { + csmap_pcost_insert(&costs, next, new_cost); + next.priorty = new_cost + abs(goal.x - next.x) + abs(goal.y - next.y); + cpque_point_push(&front, next); + csmap_pstep_insert(&from, next, current); + } + } + } + } + point current = goal; + while (!point_equal(¤t, &start)) + { + cdeq_point_push_front(&ret_path, current); + current = *csmap_pstep_at(&from, current); + } + cdeq_point_push_front(&ret_path, start); + } + return ret_path; +} + +int +main(void) +{ + cstr maze = cstr_lit( + "#########################################################################\n" + "# # # # # # #\n" + "# # ######### # ##### ######### ##### ##### ##### # ! #\n" + "# # # # # # # # # #\n" + "######### # ######### ######### ##### # # # ######### #\n" + "# # # # # # # # # # #\n" + "# # ############# # # ######### ##### # ######### # #\n" + "# # # # # # # # # #\n" + "# ############# ##### ##### # ##### ######### # ##### #\n" + "# # # # # # # # # #\n" + "# ##### ##### # ##### # ######### # # # #############\n" + "# # # # # # # # # # # #\n" + "############# # # # ######### # ##### # ##### ##### #\n" + "# # # # # # # # # #\n" + "# ##### # ######### ##### # ##### ##### ############# #\n" + "# # # # # # # # # #\n" + "# # ######### # ##### ######### # # ############# # #\n" + "# # # # # # # # # # #\n" + "# ######### # # # ##### ######### ######### # #########\n" + "# # # # # # # # # #\n" + "# @ # ##### ##### ##### ######### ##### # ######### # #\n" + "# # # # # # #\n" + "#########################################################################\n" + ); + int width = (int)cstr_find(&maze, "\n") + 1; + cdeq_point ret_path = astar(&maze, width); + + c_foreach (it, cdeq_point, ret_path) + cstr_data(&maze)[point_index(it.ref)] = 'x'; + + printf("%s", cstr_str(&maze)); + + cdeq_point_drop(&ret_path); + cstr_drop(&maze); +} diff --git a/misc/examples/mixed/complex.c b/misc/examples/mixed/complex.c new file mode 100644 index 00000000..4eb1574b --- /dev/null +++ b/misc/examples/mixed/complex.c @@ -0,0 +1,49 @@ + +// Define similar c++ data types: +// +// using FloatStack = std::stack; +// using StackList = std::stack; +// using ListMap = std::unordered_map>; +// using MapMap = std::unordered_map; +#define i_implement +#include + +#define i_type FloatStack +#define i_key float +#include + +#define i_type StackList +#define i_keyclass FloatStack // "class" picks up _clone, _drop, _cmp +#define i_opt c_no_cmp // exclude FloatStack_cmp(): not defined +#include + +#define i_type ListMap +#define i_key int +#define i_valclass StackList // "class" picks up _clone, _drop +#include + +#define i_type MapMap +#define i_key_str +#define i_valclass ListMap +#include + + +int main(void) +{ + MapMap mmap = {0}; + + // Put in some data in the structures + ListMap* lmap = &MapMap_emplace(&mmap, "first", ListMap_init()).ref->second; + StackList* list = &ListMap_insert(lmap, 42, StackList_init()).ref->second; + FloatStack* stack = StackList_push_back(list, FloatStack_with_size(10, 0)); + stack->data[3] = 3.1415927f; + printf("stack size: %" c_ZI "\n", FloatStack_size(stack)); + + // Access the data entry + 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", (double)*FloatStack_at(stack_p, 3)); // pi + + MapMap_drop(&mmap); +} diff --git a/misc/examples/mixed/convert.c b/misc/examples/mixed/convert.c new file mode 100644 index 00000000..fa64560e --- /dev/null +++ b/misc/examples/mixed/convert.c @@ -0,0 +1,57 @@ +#define i_implement +#include + +#define i_key_str +#define i_val_str +#include + +#define i_key_str +#include + +#define i_key_str +#include + +int main(void) +{ + cmap_str map, mclone; + cvec_str keys = {0}, values = {0}; + clist_str list = {0}; + + c_defer( + cmap_str_drop(&map), + cmap_str_drop(&mclone), + cvec_str_drop(&keys), + cvec_str_drop(&values), + clist_str_drop(&list) + ){ + map = c_init(cmap_str, { + {"green", "#00ff00"}, + {"blue", "#0000ff"}, + {"yellow", "#ffff00"}, + }); + + puts("MAP:"); + c_foreach (i, cmap_str, map) + printf(" %s: %s\n", cstr_str(&i.ref->first), cstr_str(&i.ref->second)); + + puts("\nCLONE MAP:"); + mclone = cmap_str_clone(map); + c_foreach (i, cmap_str, mclone) + printf(" %s: %s\n", cstr_str(&i.ref->first), cstr_str(&i.ref->second)); + + puts("\nCOPY MAP TO VECS:"); + c_foreach (i, cmap_str, mclone) { + cvec_str_emplace_back(&keys, cstr_str(&i.ref->first)); + cvec_str_emplace_back(&values, cstr_str(&i.ref->second)); + } + c_forrange (i, cvec_str_size(&keys)) + printf(" %s: %s\n", cstr_str(keys.data + i), cstr_str(values.data + i)); + + puts("\nCOPY VEC TO LIST:"); + c_foreach (i, cvec_str, keys) + clist_str_emplace_back(&list, cstr_str(i.ref)); + + c_foreach (i, clist_str, list) + printf(" %s\n", cstr_str(i.ref)); + } +} diff --git a/misc/examples/mixed/demos.c b/misc/examples/mixed/demos.c new file mode 100644 index 00000000..1a604d9f --- /dev/null +++ b/misc/examples/mixed/demos.c @@ -0,0 +1,194 @@ +#define i_implement +#include + +void stringdemo1(void) +{ + cstr cs = cstr_lit("one-nine-three-seven-five"); + printf("%s.\n", cstr_str(&cs)); + + cstr_insert(&cs, 3, "-two"); + printf("%s.\n", cstr_str(&cs)); + + cstr_erase(&cs, 7, 5); // -nine + printf("%s.\n", cstr_str(&cs)); + + cstr_replace(&cs, "seven", "four", 1); + printf("%s.\n", cstr_str(&cs)); + + cstr_take(&cs, cstr_from_fmt("%s *** %s", cstr_str(&cs), cstr_str(&cs))); + printf("%s.\n", cstr_str(&cs)); + + printf("find \"four\": %s\n", cstr_str(&cs) + cstr_find(&cs, "four")); + + // reassign: + cstr_assign(&cs, "one two three four five six seven"); + cstr_append(&cs, " eight"); + printf("append: %s\n", cstr_str(&cs)); + + cstr_drop(&cs); +} + +#define i_key int64_t +#define i_tag ix +#include + +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]); + 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]); + } + + cvec_ix_drop(&bignums); +} + +#define i_key_str +#include + +void vectordemo2(void) +{ + cvec_str names = {0}; + cvec_str_emplace_back(&names, "Mary"); + cvec_str_emplace_back(&names, "Joe"); + cvec_str_emplace_back(&names, "Chris"); + cstr_assign(&names.data[1], "Jane"); // replace Joe + printf("names[1]: %s\n", cstr_str(&names.data[1])); + + cvec_str_sort(&names); // Sort the array + + c_foreach (i, cvec_str, names) + printf("sorted: %s\n", cstr_str(i.ref)); + + cvec_str_drop(&names); +} + +#define i_key int +#define i_tag ix +#define i_cmp_native +#include + +void listdemo1(void) +{ + clist_ix nums = {0}, nums2 = {0}; + for (int i = 0; i < 10; ++i) + clist_ix_push_back(&nums, i); + for (int i = 100; i < 110; ++i) + clist_ix_push_back(&nums2, i); + + /* splice nums2 to front of nums */ + clist_ix_splice(&nums, clist_ix_begin(&nums), &nums2); + c_foreach (i, clist_ix, nums) + printf("spliced: %d\n", *i.ref); + puts(""); + + *clist_ix_find(&nums, 104).ref += 50; + clist_ix_remove(&nums, 103); + clist_ix_iter it = clist_ix_begin(&nums); + clist_ix_erase_range(&nums, clist_ix_advance(it, 5), clist_ix_advance(it, 15)); + clist_ix_pop_front(&nums); + clist_ix_push_back(&nums, -99); + clist_ix_sort(&nums); + + c_foreach (i, clist_ix, nums) + printf("sorted: %d\n", *i.ref); + + c_drop(clist_ix, &nums, &nums2); +} + +#define i_key int +#define i_tag i +#include + +void setdemo1(void) +{ + cset_i nums = {0}; + cset_i_insert(&nums, 8); + cset_i_insert(&nums, 11); + + c_foreach (i, cset_i, nums) + printf("set: %d\n", *i.ref); + cset_i_drop(&nums); +} + +#define i_key int +#define i_val int +#define i_tag ii +#include + +void mapdemo1(void) +{ + cmap_ii nums = {0}; + cmap_ii_insert(&nums, 8, 64); + cmap_ii_insert(&nums, 11, 121); + printf("val 8: %d\n", *cmap_ii_at(&nums, 8)); + cmap_ii_drop(&nums); +} + +#define i_key_str +#define i_val int +#define i_tag si +#include + +void mapdemo2(void) +{ + cmap_si nums = {0}; + cmap_si_emplace_or_assign(&nums, "Hello", 64); + cmap_si_emplace_or_assign(&nums, "Groovy", 121); + cmap_si_emplace_or_assign(&nums, "Groovy", 200); // overwrite previous + + // iterate the map: + for (cmap_si_iter i = cmap_si_begin(&nums); i.ref; cmap_si_next(&i)) + printf("long: %s: %d\n", cstr_str(&i.ref->first), i.ref->second); + + // or rather use the short form: + c_foreach (i, cmap_si, nums) + printf("short: %s: %d\n", cstr_str(&i.ref->first), i.ref->second); + + cmap_si_drop(&nums); +} + +#define i_key_str +#define i_val_str +#include + +void mapdemo3(void) +{ + cmap_str table = {0}; + cmap_str_emplace(&table, "Map", "test"); + cmap_str_emplace(&table, "Make", "my"); + cmap_str_emplace(&table, "Sunny", "day"); + cmap_str_iter it = cmap_str_find(&table, "Make"); + c_foreach (i, cmap_str, table) + printf("entry: %s: %s\n", cstr_str(&i.ref->first), cstr_str(&i.ref->second)); + printf("size %" c_ZI ": remove: Make: %s\n", cmap_str_size(&table), cstr_str(&it.ref->second)); + //cmap_str_erase(&table, "Make"); + cmap_str_erase_at(&table, it); + + printf("size %" c_ZI "\n", cmap_str_size(&table)); + c_foreach (i, cmap_str, table) + printf("entry: %s: %s\n", cstr_str(&i.ref->first), cstr_str(&i.ref->second)); + + cmap_str_drop(&table); // frees key and value cstrs, and hash table. +} + +int main(void) +{ + printf("\nSTRINGDEMO1\n"); stringdemo1(); + printf("\nVECTORDEMO1\n"); vectordemo1(); + printf("\nVECTORDEMO2\n"); vectordemo2(); + printf("\nLISTDEMO1\n"); listdemo1(); + printf("\nSETDEMO1\n"); setdemo1(); + printf("\nMAPDEMO1\n"); mapdemo1(); + printf("\nMAPDEMO2\n"); mapdemo2(); + printf("\nMAPDEMO3\n"); mapdemo3(); +} diff --git a/misc/examples/mixed/inits.c b/misc/examples/mixed/inits.c new file mode 100644 index 00000000..53a49f1f --- /dev/null +++ b/misc/examples/mixed/inits.c @@ -0,0 +1,108 @@ +#define i_implement +#include + +#define i_key int +#define i_val_str +#define i_tag id // Map of int => cstr +#include + +#define i_key_str +#define i_val int +#define i_tag cnt // Map of cstr => int +#include + +typedef struct {int x, y;} ipair_t; +inline static int ipair_cmp(const ipair_t* a, const ipair_t* b) { + int c = c_default_cmp(&a->x, &b->x); + return c ? c : c_default_cmp(&a->y, &b->y); +} + + +#define i_key ipair_t +#define i_cmp ipair_cmp +#define i_tag ip +#include + +#define i_key ipair_t +#define i_cmp ipair_cmp +#define i_tag ip +#include + +#define i_key float +#define i_tag f +#include + +int main(void) +{ + // CVEC FLOAT / PRIORITY QUEUE + + cpque_f floats = {0}; + const float nums[] = {4.0f, 2.0f, 5.0f, 3.0f, 1.0f}; + + // PRIORITY QUEUE + c_forrange (i, c_arraylen(nums)) + cpque_f_push(&floats, nums[i]); + + puts("\npop and show high priorites first:"); + while (! cpque_f_empty(&floats)) { + printf("%.1f ", (double)*cpque_f_top(&floats)); + cpque_f_pop(&floats); + } + puts("\n"); + cpque_f_drop(&floats); + + // CMAP ID + + int year = 2020; + cmap_id idnames = {0}; + cmap_id_emplace(&idnames, 100, "Hello"); + cmap_id_insert(&idnames, 110, cstr_lit("World")); + cmap_id_insert(&idnames, 120, cstr_from_fmt("Howdy, -%d-", year)); + + c_foreach (i, cmap_id, idnames) + printf("%d: %s\n", i.ref->first, cstr_str(&i.ref->second)); + puts(""); + cmap_id_drop(&idnames); + + // CMAP CNT + + cmap_cnt countries = c_init(cmap_cnt, { + {"Norway", 100}, + {"Denmark", 50}, + {"Iceland", 10}, + {"Belgium", 10}, + {"Italy", 10}, + {"Germany", 10}, + {"Spain", 10}, + {"France", 10}, + }); + cmap_cnt_emplace(&countries, "Greenland", 0).ref->second += 20; + cmap_cnt_emplace(&countries, "Sweden", 0).ref->second += 20; + cmap_cnt_emplace(&countries, "Norway", 0).ref->second += 20; + cmap_cnt_emplace(&countries, "Finland", 0).ref->second += 20; + + c_forpair (country, health, cmap_cnt, countries) + printf("%s: %d\n", cstr_str(_.country), *_.health); + puts(""); + cmap_cnt_drop(&countries); + + // CVEC PAIR + + 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) + printf("(%d %d) ", i.ref->x, i.ref->y); + puts(""); + cvec_ip_drop(&pairs1); + + // CLIST PAIR + + 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) + printf("(%d %d) ", i.ref->x, i.ref->y); + puts(""); + clist_ip_drop(&pairs2); +} diff --git a/misc/examples/mixed/read.c b/misc/examples/mixed/read.c new file mode 100644 index 00000000..de04fd31 --- /dev/null +++ b/misc/examples/mixed/read.c @@ -0,0 +1,27 @@ +#define i_implement +#include +#include +#define i_key_str +#include +#include + +cvec_str read_file(const char* name) +{ + cvec_str vec = {0}; + c_with (FILE* f = fopen(name, "r"), fclose(f)) + c_with (cstr line = {0}, cstr_drop(&line)) + while (cstr_getline(&line, f)) + cvec_str_push(&vec, cstr_clone(line)); + return vec; +} + +int main(void) +{ + int n = 0; + c_with (cvec_str vec = read_file(__FILE__), cvec_str_drop(&vec)) + c_foreach (i, cvec_str, vec) + printf("%5d: %s\n", ++n, cstr_str(i.ref)); + + if (errno) + printf("error: read_file(" __FILE__ "). errno: %d\n", errno); +} diff --git a/misc/examples/mmap.c b/misc/examples/mmap.c deleted file mode 100644 index 04a605a7..00000000 --- a/misc/examples/mmap.c +++ /dev/null @@ -1,65 +0,0 @@ -// This implements the multimap c++ example found at: -// https://en.cppreference.com/w/cpp/container/multimap/insert - -// Multimap entries -#define i_implement -#include -#define i_key_str -#include - -// Map of int => clist_str. -#define i_type Multimap -#define i_key int -#define i_valclass clist_str // set i_val = clist_str, bind clist_str_clone and clist_str_drop -#define i_cmp -c_default_cmp // like std::greater -#include - -void print(const char* lbl, const Multimap mmap) -{ - printf("%s ", lbl); - c_foreach (e, Multimap, mmap) { - c_foreach (s, clist_str, e.ref->second) - printf("{%d,%s} ", e.ref->first, cstr_str(s.ref)); - } - puts(""); -} - -void insert(Multimap* mmap, int key, const char* str) -{ - clist_str *list = &Multimap_insert(mmap, key, clist_str_init()).ref->second; - clist_str_emplace_back(list, str); -} - -int main(void) -{ - Multimap mmap = {0}; - - // list-initialize - typedef struct {int a; const char* b;} pair; - c_forlist (i, pair, {{2, "foo"}, {2, "bar"}, {3, "baz"}, {1, "abc"}, {5, "def"}}) - insert(&mmap, i.ref->a, i.ref->b); - print("#1", mmap); - - // insert using value_type - insert(&mmap, 5, "pqr"); - print("#2", mmap); - - // insert using make_pair - insert(&mmap, 6, "uvw"); - print("#3", mmap); - - insert(&mmap, 7, "xyz"); - print("#4", mmap); - - // insert using initialization_list - c_forlist (i, pair, {{5, "one"}, {5, "two"}}) - insert(&mmap, i.ref->a, i.ref->b); - print("#5", mmap); - - // FOLLOWING NOT IN ORIGINAL EXAMPLE: - // erase all entries with key 5 - Multimap_erase(&mmap, 5); - print("+5", mmap); - - Multimap_drop(&mmap); -} diff --git a/misc/examples/multidim.c b/misc/examples/multidim.c deleted file mode 100644 index 798a1126..00000000 --- a/misc/examples/multidim.c +++ /dev/null @@ -1,67 +0,0 @@ -// Example based on https://en.cppreference.com/w/cpp/container/mdspan -#define i_val int -#include -#include -#include - -using_cspan3(ispan, int); - -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}); - - // 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; - 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/multimap.c b/misc/examples/multimap.c deleted file mode 100644 index 1068a5dc..00000000 --- a/misc/examples/multimap.c +++ /dev/null @@ -1,102 +0,0 @@ -#define i_implement -#include - -// Olympics multimap example - -struct OlympicsData { int year; const char *city, *country, *date; } ol_data[] = { - {2026, "Milan and Cortina d'Ampezzo", "Italy", "February 6-22"}, - {2022, "Beijing", "China", "February 4-20"}, - {2018, "PyeongChang", "South Korea", "February 9-25"}, - {2014, "Sochi", "Russia", "February 7-23"}, - {2010, "Vancouver", "Canada", "February 12-28"}, - {2006, "Torino", "Italy", "February 10-26"}, - {2002, "Salt Lake City", "United States", "February 8-24"}, - {1998, "Nagano", "Japan", "February 7-22"}, - {1994, "Lillehammer", "Norway", "February 12-27"}, - {1992, "Albertville", "France", "February 8-23"}, - {1988, "Calgary", "Canada", "February 13-28"}, - {1984, "Sarajevo", "Yugoslavia", "February 8-19"}, - {1980, "Lake Placid", "United States", "February 13-24"}, - {1976, "Innsbruck", "Austria", "February 4-15"}, - {1972, "Sapporo", "Japan", "February 3-13"}, - {1968, "Grenoble", "France", "February 6-18"}, - {1964, "Innsbruck", "Austria", "January 29-February 9"}, - {1960, "Squaw Valley", "United States", "February 18-28"}, - {1956, "Cortina d'Ampezzo", "Italy", "January 26 - February 5"}, - {1952, "Oslo", "Norway", "February 14 - 25"}, - {1948, "St. Moritz", "Switzerland", "January 30 - February 8"}, - {1944, "canceled", "canceled", "canceled"}, - {1940, "canceled", "canceled", "canceled"}, - {1936, "Garmisch-Partenkirchen", "Germany", "February 6 - 16"}, - {1932, "Lake Placid", "United States", "February 4 - 15"}, - {1928, "St. Moritz", "Switzerland", "February 11 - 19"}, - {1924, "Chamonix", "France", "January 25 - February 5"}, -}; - -typedef struct { int year; cstr city, date; } OlympicLoc; - -int OlympicLoc_cmp(const OlympicLoc* a, const OlympicLoc* b); -OlympicLoc OlympicLoc_clone(OlympicLoc loc); -void OlympicLoc_drop(OlympicLoc* self); - -// Create a clist, can be sorted by year. -#define i_keyclass OlympicLoc // binds _cmp, _clone and _drop. -#define i_tag OL -#include - -// Create a csmap where key is country name -#define i_key_str // binds cstr_equ, cstr_hash, cstr_clone, ++ -#define i_valclass clist_OL // binds clist_OL_clone, clist_OL_drop -#define i_tag OL -#include - -int OlympicLoc_cmp(const OlympicLoc* a, const OlympicLoc* b) { - return a->year - b->year; -} - -OlympicLoc OlympicLoc_clone(OlympicLoc loc) { - loc.city = cstr_clone(loc.city); - loc.date = cstr_clone(loc.date); - return loc; -} - -void OlympicLoc_drop(OlympicLoc* self) { - cstr_drop(&self->city); - cstr_drop(&self->date); -} - - -int main(void) -{ - // Define the multimap with destructor defered to when block is completed. - csmap_OL multimap = {0}; - const clist_OL empty = clist_OL_init(); - - for (size_t i = 0; i < c_arraylen(ol_data); ++i) - { - struct OlympicsData* d = &ol_data[i]; - OlympicLoc loc = {.year = d->year, - .city = cstr_from(d->city), - .date = cstr_from(d->date)}; - // Insert an empty list for each new country, and append the entry to the list. - // If country already exist in map, its list is returned from the insert function. - clist_OL* list = &csmap_OL_emplace(&multimap, d->country, empty).ref->second; - clist_OL_push_back(list, loc); - } - - // Sort locations by year for each country. - c_foreach (country, csmap_OL, multimap) - clist_OL_sort(&country.ref->second); - - // Print the multimap: - c_foreach (country, csmap_OL, multimap) - { - // Loop the locations for a country sorted by year - c_foreach (loc, clist_OL, country.ref->second) - printf("%s: %d, %s, %s\n", cstr_str(&country.ref->first), - loc.ref->year, - cstr_str(&loc.ref->city), - cstr_str(&loc.ref->date)); - } - csmap_OL_drop(&multimap); -} diff --git a/misc/examples/music_arc.c b/misc/examples/music_arc.c deleted file mode 100644 index 16111b0b..00000000 --- a/misc/examples/music_arc.c +++ /dev/null @@ -1,67 +0,0 @@ -// 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 - -typedef struct -{ - cstr artist; - cstr title; -} Song; - -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 c_LITERAL(Song){cstr_from(artist), cstr_from(title)}; } - -void Song_drop(Song* s) { - printf("drop: %s\n", cstr_str(&s->title)); - c_drop(cstr, &s->artist, &s->title); -} - -// Define the shared pointer: -#define i_type SongArc -#define i_keyclass Song -#define i_no_hash // no hash fn for Song, fallback hash pointer to Song. -#include - -// ... and a vector of them -#define i_type SongVec -#define i_keyboxed SongArc // use i_keyboxed on carc / cbox (instead of i_key) -#include - -void example3(void) -{ - SongVec vec1 = c_init(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 vec2 = {0}; - // Share all entries in vec with vec2, except Bob Dylan. - c_foreach (s, SongVec, vec1) - if (!cstr_equals(&s.ref->get->artist, "Bob Dylan")) - SongVec_push(&vec2, SongArc_clone(*s.ref)); - - // 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")); - - // We now have two vectors with some shared, some unique entries. - c_forlist (i, SongVec, {vec1, vec2}) { - puts("VEC:"); - c_foreach (s, SongVec, *i.ref) - printf(" %s - %s, REFS: %ld\n", cstr_str(&s.ref->get->artist), - cstr_str(&s.ref->get->title), - *s.ref->use_count); - } - c_drop(SongVec, &vec1, &vec2); -} - -int main(void) -{ - example3(); -} diff --git a/misc/examples/new_list.c b/misc/examples/new_list.c deleted file mode 100644 index 2112bf1f..00000000 --- a/misc/examples/new_list.c +++ /dev/null @@ -1,70 +0,0 @@ -#include -#include - -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 - -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 - -#define i_key float -#define i_cmp_native // use < and == operators for comparison -#include - -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 - -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/new_map.c b/misc/examples/new_map.c deleted file mode 100644 index de990040..00000000 --- a/misc/examples/new_map.c +++ /dev/null @@ -1,75 +0,0 @@ -#define i_implement -#include -#include - -forward_cmap(cmap_pnt, struct Point, int); - -typedef struct MyStruct { - cmap_pnt pntmap; - cstr name; -} MyStruct; - -// int => int map -#define i_key int -#define i_val int -#include - -// Point => int map -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; -} - -// Point => int map -#define i_key Point -#define i_val int -#define i_cmp point_cmp -#define i_hash c_default_hash -#define i_is_forward -#define i_tag pnt -#include - -// cstr => cstr map -#define i_key_str -#define i_val_str -#include - -// string set -#define i_key_str -#include - - -int main(void) -{ - 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_init(cmap_str, { - {"Hello, friend", "long time no see"}, - {"So long", "see you around"}, - }); - - cset_str sset = c_init(cset_str, { - "Hello, friend", - "Nice to see you again", - "So long", - }); - - cmap_int map = {0}; - cmap_int_insert(&map, 123, 321); - cmap_int_insert(&map, 456, 654); - cmap_int_insert(&map, 789, 987); - - c_foreach (i, cset_str, sset) - printf(" %s\n", cstr_str(i.ref)); - - cmap_int_drop(&map); - cset_str_drop(&sset); - cmap_str_drop(&smap); - cmap_pnt_drop(&pmap); -} diff --git a/misc/examples/new_pque.c b/misc/examples/new_pque.c deleted file mode 100644 index 16823bb6..00000000 --- a/misc/examples/new_pque.c +++ /dev/null @@ -1,22 +0,0 @@ -#include - -typedef struct Point { int x, y; } Point; - -#define i_type PointQ -#define i_key Point -#define i_less(a, b) a->x < b->x || (a->x == b->x && a->y < b->y) -#include - - -int main(void) -{ - PointQ pque = c_init(PointQ, {{23, 80}, {12, 32}, {54, 74}, {12, 62}}); - // print - for (; !PointQ_empty(&pque); PointQ_pop(&pque)) - { - const Point *v = PointQ_top(&pque); - printf(" (%d,%d)", v->x, v->y); - } - puts(""); - PointQ_drop(&pque); -} diff --git a/misc/examples/new_queue.c b/misc/examples/new_queue.c deleted file mode 100644 index f3592df6..00000000 --- a/misc/examples/new_queue.c +++ /dev/null @@ -1,47 +0,0 @@ -#include -#include -#include -#include - -forward_cqueue(cqueue_pnt, struct 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_key Point -#define i_cmp point_cmp -#define i_is_forward -#define i_tag pnt -#include - -#define i_type IQ -#define i_key int -#include - -int main(void) { - int n = 50000000; - crand_t rng = crand_init((uint64_t)time(NULL)); - crand_unif_t dist = crand_unif_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)); - - // 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); - if (r & 3) - IQ_push(&Q, r); - else - IQ_pop(&Q); - } - - printf("after: size %" c_ZI ", capacity %" c_ZI "\n", IQ_size(&Q), IQ_capacity(&Q)); - IQ_drop(&Q); -} diff --git a/misc/examples/new_smap.c b/misc/examples/new_smap.c deleted file mode 100644 index ee946c9a..00000000 --- a/misc/examples/new_smap.c +++ /dev/null @@ -1,67 +0,0 @@ -#define i_implement -#include -#include - -forward_csmap(PMap, struct Point, int); - -// Use forward declared PMap in struct -typedef struct { - PMap pntmap; - cstr name; -} MyStruct; - -// Point => int map -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_type PMap -#define i_key Point -#define i_val int -#define i_cmp point_cmp -#define i_is_forward -#include - -// cstr => cstr map -#define i_type SMap -#define i_key_str -#define i_val_str -#include - -// cstr set -#define i_type SSet -#define i_key_str -#include - - -int main(void) -{ - PMap pmap = c_init(PMap, { - {{42, 14}, 1}, - {{32, 94}, 2}, - {{62, 81}, 3}, - }); - SMap smap = c_init(SMap, { - {"Hello, friend", "this is the mapped value"}, - {"The brown fox", "jumped"}, - {"This is the time", "for all good things"}, - }); - SSet sset = {0}; - - c_forpair (p, i, PMap, pmap) - printf(" (%d,%d: %d)", _.p->x, _.p->y, *_.i); - puts(""); - - c_forpair (i, j, SMap, smap) - printf(" (%s: %s)\n", cstr_str(_.i), cstr_str(_.j)); - - SSet_emplace(&sset, "Hello, friend"); - SSet_emplace(&sset, "Goodbye, foe"); - printf("Found? %s\n", SSet_contains(&sset, "Hello, friend") ? "true" : "false"); - - PMap_drop(&pmap); - SMap_drop(&smap); - SSet_drop(&sset); -} diff --git a/misc/examples/new_sptr.c b/misc/examples/new_sptr.c deleted file mode 100644 index 3c6fa16c..00000000 --- a/misc/examples/new_sptr.c +++ /dev/null @@ -1,75 +0,0 @@ -#define i_implement -#include - -typedef struct { cstr name, last; } Person; -Person Person_make(const char* name, const char* last); -Person Person_clone(Person p); -void Person_drop(Person* p); -int Person_cmp(const Person* a, const Person* b); -uint64_t Person_hash(const Person* p); - -#define i_type PersonArc -#define i_keyclass Person // "class" assume _clone, _drop, _cmp, _hash is defined. -#include - -#define i_type IPtr -#define i_key int -#define i_keydrop(x) printf("drop: %d\n", *x) -#define i_cmp_native -#include - -#define i_type IPStack -#define i_keyboxed IPtr -#include - -#define i_type PASet -#define i_keyboxed PersonArc -#include - - -Person Person_make(const char* name, const char* last) { - Person p = {.name = cstr_from(name), .last = cstr_from(last)}; - return p; -} - -int Person_cmp(const Person* a, const Person* b) { - return cstr_cmp(&a->name, &b->name); -} - -uint64_t Person_hash(const Person* p) { - return cstr_hash(&p->name); -} - -Person Person_clone(Person p) { - p.name = cstr_clone(p.name), p.last = cstr_clone(p.last); - return p; -} - -void Person_drop(Person* p) { - printf("drop: %s %s\n", cstr_str(&p->name), cstr_str(&p->last)); - c_drop(cstr, &p->name, &p->last); -} - - -int main(void) { - puts("Ex1"); - PersonArc p = PersonArc_from(Person_make("John", "Smiths")); - PersonArc q = PersonArc_clone(p); // share - PersonArc r = PersonArc_clone(p); - PersonArc s = PersonArc_from(Person_clone(*p.get)); // deep copy - printf("%s %s: refs %ld\n", cstr_str(&p.get->name), cstr_str(&p.get->last), *p.use_count); - c_drop(PersonArc, &p, &q, &r, &s); - - puts("Ex2"); - IPStack vec = {0}; - IPStack_push(&vec, IPtr_from(10)); - IPStack_push(&vec, IPtr_from(20)); - IPStack_emplace(&vec, 30); // same as IPStack_push(&vec, IPtr_from(30)); - IPStack_push(&vec, IPtr_clone(*IPStack_back(&vec))); - IPStack_push(&vec, IPtr_clone(*IPStack_front(&vec))); - - c_foreach (i, IPStack, vec) - printf(" (%d: refs %ld)", *i.ref->get, *i.ref->use_count); - puts(""); - IPStack_drop(&vec); -} diff --git a/misc/examples/new_vec.c b/misc/examples/new_vec.c deleted file mode 100644 index 88efd55a..00000000 --- a/misc/examples/new_vec.c +++ /dev/null @@ -1,43 +0,0 @@ -#include -#include - -forward_cvec(cvec_i32, int); -forward_cvec(cvec_pnt, struct Point); - -typedef struct MyStruct { - cvec_i32 intvec; - cvec_pnt pntvec; -} MyStruct; - -#define i_key int -#define i_tag i32 -#define i_is_forward -#include - -typedef struct Point { int x, y; } 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 -#include - -int main(void) -{ - MyStruct my = {0}; - - 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); - - c_foreach (i, cvec_pnt, my.pntvec) - printf(" (%d %d)", i.ref->x, i.ref->y); - puts(""); - - cvec_i32_drop(&my.intvec); - cvec_pnt_drop(&my.pntvec); -} diff --git a/misc/examples/person_arc.c b/misc/examples/person_arc.c deleted file mode 100644 index 38c883a7..00000000 --- a/misc/examples/person_arc.c +++ /dev/null @@ -1,77 +0,0 @@ -/* cbox: heap allocated boxed type */ -#define i_implement -#include - -typedef struct { cstr name, last; } Person; - -Person Person_make(const char* name, const char* last) { - Person p = {.name = cstr_from(name), .last = cstr_from(last)}; - return p; -} - -int Person_cmp(const Person* a, const Person* b) { - int c = cstr_cmp(&a->name, &b->name); - return c ? c : cstr_cmp(&a->last, &b->last); -} - -uint64_t Person_hash(const Person* a) { - return cstr_hash(&a->name) ^ cstr_hash(&a->last); -} - -Person Person_clone(Person p) { - p.name = cstr_clone(p.name); - p.last = cstr_clone(p.last); - return p; -} - -void Person_drop(Person* p) { - printf("drop: %s %s\n", cstr_str(&p->name), cstr_str(&p->last)); - c_drop(cstr, &p->name, &p->last); -} - -#define i_type PSPtr -#define i_keyclass Person // ensure Person_drop -#define i_cmp Person_cmp // specify object cmp, instead of ptr cmp for arc. -#include - -#define i_type Persons -#define i_keyboxed PSPtr // binds PSPtr_cmp, PSPtr_drop... -#include - - -int main(void) -{ - PSPtr p = PSPtr_from(Person_make("Laura", "Palmer")); - PSPtr q = PSPtr_from(Person_clone(*p.get)); // deep copy - Persons vec = {0}; - - c_defer( - PSPtr_drop(&p), - PSPtr_drop(&q), - Persons_drop(&vec) - ){ - cstr_assign(&q.get->name, "Leland"); - - printf("orig: %s %s\n", cstr_str(&p.get->name), cstr_str(&p.get->last)); - printf("copy: %s %s\n", cstr_str(&q.get->name), cstr_str(&q.get->last)); - - // Use Persons_emplace to implicitly call PSPtr_make on the argument. - // No need to do: Persons_push(&vec, PSPtr_make(Person_make("Audrey", "Home"))); - Persons_emplace(&vec, Person_make("Audrey", "Home")); - Persons_emplace(&vec, Person_make("Dale", "Cooper")); - - // Clone/share p and q to the vector - c_forlist (i, PSPtr, {p, q}) - Persons_push(&vec, PSPtr_clone(*i.ref)); - - c_foreach (i, Persons, vec) - printf("%s %s\n", cstr_str(&i.ref->get->name), cstr_str(&i.ref->get->last)); - puts(""); - - // Look-up Audrey! - Person a = Person_make("Audrey", "Home"); - const PSPtr *v = Persons_get(&vec, a); - if (v) printf("found: %s %s\n", cstr_str(&v->get->name), cstr_str(&v->get->last)); - Person_drop(&a); - } -} diff --git a/misc/examples/phonebook.c b/misc/examples/phonebook.c deleted file mode 100644 index faf7566e..00000000 --- a/misc/examples/phonebook.c +++ /dev/null @@ -1,72 +0,0 @@ -// The MIT License (MIT) -// Copyright (c) 2018 Maksim Andrianov -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. - -// Program to emulates the phone book. -#define i_implement -#include - -#define i_key_str -#define i_val_str -#include - -#define i_key_str -#include - -void print_phone_book(cmap_str phone_book) -{ - c_foreach (i, cmap_str, phone_book) - printf("%s\t- %s\n", cstr_str(&i.ref->first), cstr_str(&i.ref->second)); -} - -int main(int argc, char **argv) -{ - cmap_str phone_book = c_init(cmap_str, { - {"Lilia Friedman", "(892) 670-4739"}, - {"Tariq Beltran", "(489) 600-7575"}, - {"Laiba Juarez", "(303) 885-5692"}, - {"Elliott Mooney", "(945) 616-4482"}, - }); - - printf("Phone book:\n"); - print_phone_book(phone_book); - - cmap_str_emplace(&phone_book, "Zak Byers", "(551) 396-1880"); - cmap_str_emplace(&phone_book, "Zak Byers", "(551) 396-1990"); - - printf("\nPhone book after adding Zak Byers:\n"); - print_phone_book(phone_book); - - if (cmap_str_contains(&phone_book, "Tariq Beltran")) - printf("\nTariq Beltran is in phone book\n"); - - cmap_str_erase(&phone_book, "Tariq Beltran"); - cmap_str_erase(&phone_book, "Elliott Mooney"); - - printf("\nPhone book after erasing Tariq and Elliott:\n"); - print_phone_book(phone_book); - - cmap_str_emplace_or_assign(&phone_book, "Zak Byers", "(555) 396-188"); - - printf("\nPhone book after update phone of Zak Byers:\n"); - print_phone_book(phone_book); - - cmap_str_drop(&phone_book); -} diff --git a/misc/examples/prime.c b/misc/examples/prime.c deleted file mode 100644 index cb3b095a..00000000 --- a/misc/examples/prime.c +++ /dev/null @@ -1,56 +0,0 @@ -#include -#include -#include -#include -#include -#include - - -cbits sieveOfEratosthenes(int64_t 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; - 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) - cbits_reset(&bits, j>>1); - } - return bits; -} - -int main(void) -{ - int n = 1000000000; - printf("Computing prime numbers up to %d\n", n); - - clock_t t = clock(); - cbits primes = sieveOfEratosthenes(n + 1); - int np = (int)cbits_count(&primes); - t = clock() - t; - - puts("Show all the primes in the range [2, 1000):"); - printf("2"); - c_forrange (i, 3, 1000, 2) - if (cbits_test(&primes, i>>1)) printf(" %lld", i); - puts("\n"); - - puts("Show the last 50 primes using a temporary crange generator:"); - crange range = crange_make(n - 1, 0, -2); - - c_forfilter (i, crange, range, - cbits_test(&primes, *i.ref/2) && - c_flt_take(i, 50) - ){ - printf("%lld ", *i.ref); - if (c_flt_getcount(i) % 10 == 0) puts(""); - } - printf("Number of primes: %d, time: %.2f\n\n", np, (double)t/CLOCKS_PER_SEC); - - cbits_drop(&primes); -} diff --git a/misc/examples/printspan.c b/misc/examples/printspan.c deleted file mode 100644 index cd3c5f4f..00000000 --- a/misc/examples/printspan.c +++ /dev/null @@ -1,52 +0,0 @@ -// printspan.c - -#include -#define i_implement -#include -#define i_key int -#include -#define i_key int -#include -#define i_key_str -#include - -#include -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(void) -{ - intspan sp1 = cspan_init(intspan, {1, 2}); - printMe( sp1 ); - - printMe( c_init(intspan, {1, 2, 3}) ); - - int arr[] = {1, 2, 3, 4, 5, 6}; - intspan sp2 = cspan_from_array(arr); - printMe( c_LITERAL(intspan)cspan_subspan(&sp2, 1, 4) ); - - cvec_int vec = c_init(cvec_int, {1, 2, 3, 4, 5}); - printMe( c_LITERAL(intspan)cspan_from(&vec) ); - - printMe( sp2 ); - - cstack_int stk = c_init(cstack_int, {1, 2, 3, 4, 5, 6, 7}); - printMe( c_LITERAL(intspan)cspan_from(&stk) ); - - csset_str set = c_init(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); - csset_str_drop(&set); -} diff --git a/misc/examples/priority.c b/misc/examples/priority.c deleted file mode 100644 index bf2e188a..00000000 --- a/misc/examples/priority.c +++ /dev/null @@ -1,37 +0,0 @@ - -#include -#include -#include - -#define i_key int64_t -#define i_cmp -c_default_cmp // min-heap (increasing values) -#define i_tag i -#include - -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); - - 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)); - - // 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)); - - puts("Extract the hundred smallest."); - c_forrange (100) { - printf("%" PRId64 " ", *cpque_i_top(&heap)); - cpque_i_pop(&heap); - } - - cpque_i_drop(&heap); -} diff --git a/misc/examples/priorityqueues/functor.c b/misc/examples/priorityqueues/functor.c new file mode 100644 index 00000000..e3bde1dd --- /dev/null +++ b/misc/examples/priorityqueues/functor.c @@ -0,0 +1,57 @@ +// Implements c++ example: https://en.cppreference.com/w/cpp/container/priority_queue +// Example of per-instance less-function on a single priority queue type +// + +#include + +#define i_type IPQue +#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 + +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. + IPQue_ext copy = {q.less, IPQue_clone(q.get)}; + + for (printf("%s: \t", name); !IPQue_empty(©.get); IPQue_pop(©.get)) + printf("%d ", *IPQue_top(©.get)); + puts(""); + + IPQue_drop(©.get); +} + +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(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]); + puts(""); + + + // Max priority queue + IPQue_ext q1 = {.less=int_less}; + IPQue_put_n(&q1.get, data, n); + print_queue("q1", q1); + + // Min priority queue + IPQue_ext minq1 = {.less=int_greater}; + IPQue_put_n(&minq1.get, data, n); + print_queue("minq1", minq1); + + // 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/priorityqueues/new_pque.c b/misc/examples/priorityqueues/new_pque.c new file mode 100644 index 00000000..16823bb6 --- /dev/null +++ b/misc/examples/priorityqueues/new_pque.c @@ -0,0 +1,22 @@ +#include + +typedef struct Point { int x, y; } Point; + +#define i_type PointQ +#define i_key Point +#define i_less(a, b) a->x < b->x || (a->x == b->x && a->y < b->y) +#include + + +int main(void) +{ + PointQ pque = c_init(PointQ, {{23, 80}, {12, 32}, {54, 74}, {12, 62}}); + // print + for (; !PointQ_empty(&pque); PointQ_pop(&pque)) + { + const Point *v = PointQ_top(&pque); + printf(" (%d,%d)", v->x, v->y); + } + puts(""); + PointQ_drop(&pque); +} diff --git a/misc/examples/priorityqueues/priority.c b/misc/examples/priorityqueues/priority.c new file mode 100644 index 00000000..bf2e188a --- /dev/null +++ b/misc/examples/priorityqueues/priority.c @@ -0,0 +1,37 @@ + +#include +#include +#include + +#define i_key int64_t +#define i_cmp -c_default_cmp // min-heap (increasing values) +#define i_tag i +#include + +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); + + 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)); + + // 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)); + + puts("Extract the hundred smallest."); + c_forrange (100) { + printf("%" PRId64 " ", *cpque_i_top(&heap)); + cpque_i_pop(&heap); + } + + cpque_i_drop(&heap); +} diff --git a/misc/examples/queue.c b/misc/examples/queue.c deleted file mode 100644 index 56b5beb9..00000000 --- a/misc/examples/queue.c +++ /dev/null @@ -1,32 +0,0 @@ -#include -#include - -#define i_key int -#define i_tag i -#include - -int main(void) { - int n = 100000000; - crand_unif_t dist; - crand_t rng = crand_init(1234); - dist = crand_unif_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)); - - // 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); - if (r & 1) - ++n, cqueue_i_push(&queue, r); - else - --n, cqueue_i_pop(&queue); - } - printf("%d, %" c_ZI "\n", n, cqueue_i_size(&queue)); - - cqueue_i_drop(&queue); -} diff --git a/misc/examples/queues/new_queue.c b/misc/examples/queues/new_queue.c new file mode 100644 index 00000000..f3592df6 --- /dev/null +++ b/misc/examples/queues/new_queue.c @@ -0,0 +1,47 @@ +#include +#include +#include +#include + +forward_cqueue(cqueue_pnt, struct 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_key Point +#define i_cmp point_cmp +#define i_is_forward +#define i_tag pnt +#include + +#define i_type IQ +#define i_key int +#include + +int main(void) { + int n = 50000000; + crand_t rng = crand_init((uint64_t)time(NULL)); + crand_unif_t dist = crand_unif_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)); + + // 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); + if (r & 3) + IQ_push(&Q, r); + else + IQ_pop(&Q); + } + + printf("after: size %" c_ZI ", capacity %" c_ZI "\n", IQ_size(&Q), IQ_capacity(&Q)); + IQ_drop(&Q); +} diff --git a/misc/examples/queues/queue.c b/misc/examples/queues/queue.c new file mode 100644 index 00000000..56b5beb9 --- /dev/null +++ b/misc/examples/queues/queue.c @@ -0,0 +1,32 @@ +#include +#include + +#define i_key int +#define i_tag i +#include + +int main(void) { + int n = 100000000; + crand_unif_t dist; + crand_t rng = crand_init(1234); + dist = crand_unif_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)); + + // 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); + if (r & 1) + ++n, cqueue_i_push(&queue, r); + else + --n, cqueue_i_pop(&queue); + } + printf("%d, %" c_ZI "\n", n, cqueue_i_size(&queue)); + + cqueue_i_drop(&queue); +} diff --git a/misc/examples/random.c b/misc/examples/random.c deleted file mode 100644 index b7c0f277..00000000 --- a/misc/examples/random.c +++ /dev/null @@ -1,45 +0,0 @@ -#include -#include -#include - -int main(void) -{ - const int 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, %d, avg: %f\n", - (double)diff/CLOCKS_PER_SEC, N, (double)sum/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, %d, avg: %f\n", - range, (double)diff/CLOCKS_PER_SEC, N, (double)sum/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, %d, avg: %f\n", - range, (double)diff/CLOCKS_PER_SEC, N, (double)sum/N); - -} diff --git a/misc/examples/rawptr_elements.c b/misc/examples/rawptr_elements.c deleted file mode 100644 index 694ce12e..00000000 --- a/misc/examples/rawptr_elements.c +++ /dev/null @@ -1,59 +0,0 @@ -#include -#include -#define i_implement -#include - -// 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 - -// Alternatively, using cbox: -#define i_type IBox -#define i_key long -#include // unique_ptr 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 - -int main(void) -{ - // 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/read.c b/misc/examples/read.c deleted file mode 100644 index b12f7409..00000000 --- a/misc/examples/read.c +++ /dev/null @@ -1,27 +0,0 @@ -#define i_implement -#include -#include -#define i_key_str -#include -#include - -cvec_str read_file(const char* name) -{ - cvec_str vec = cvec_str_init(); - c_with (FILE* f = fopen(name, "r"), fclose(f)) - c_with (cstr line = cstr_null, cstr_drop(&line)) - while (cstr_getline(&line, f)) - cvec_str_push(&vec, cstr_clone(line)); - return vec; -} - -int main(void) -{ - int n = 0; - c_with (cvec_str vec = read_file(__FILE__), cvec_str_drop(&vec)) - c_foreach (i, cvec_str, vec) - printf("%5d: %s\n", ++n, cstr_str(i.ref)); - - if (errno) - printf("error: read_file(" __FILE__ "). errno: %d\n", errno); -} diff --git a/misc/examples/regex1.c b/misc/examples/regex1.c deleted file mode 100644 index d8032358..00000000 --- a/misc/examples/regex1.c +++ /dev/null @@ -1,32 +0,0 @@ -#define i_import -#include - -int main(int argc, char* argv[]) -{ - if (argc <= 1) { - printf("Usage: regex1 -i\n"); - return 0; - } - cstr input = {0}; - cregex float_expr = {0}; - - int res = cregex_compile(&float_expr, "^[+-]?[0-9]+((\\.[0-9]*)?|\\.[0-9]+)$"); - // Until "q" is given, ask for another number - if (res > 0) while (true) - { - printf("Enter a double precision number (q for quit): "); - cstr_getline(&input, stdin); - - // Exit when the user inputs q - if (cstr_equals(&input, "q")) - break; - - if (cregex_is_match(&float_expr, cstr_str(&input))) - printf("Input is a float\n"); - else - printf("Invalid input : Not a float\n"); - } - - cstr_drop(&input); - cregex_drop(&float_expr); -} diff --git a/misc/examples/regex2.c b/misc/examples/regex2.c deleted file mode 100644 index a798b1a1..00000000 --- a/misc/examples/regex2.c +++ /dev/null @@ -1,34 +0,0 @@ -#define i_import -#include - -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])", - "date: 2024-02-29 leapyear day, christmas eve is on 2022-12-24." - }, - {"(https?://|ftp://|www\\.)([0-9A-Za-z@:%_+~#=-]+\\.)+([a-z][a-z][a-z]?)(/[/0-9A-Za-z\\.@:%_+~#=\\?&-]*)?", - "https://en.cppreference.com/w/cpp/regex/regex_search" - }, - {"!((abc|123)+)!", "!123abcabc!"}, - {"(\\p{Alpha}+ )+(\\p{Nd}+)", "Großpackung süßigkeiten 199"}, - {"\\p{Han}+", "This is Han: 王明:那是杂志吗?"}, - }; - - cregex re = {0}; - c_forrange (i, c_arraylen(s)) - { - int res = cregex_compile(&re, s[i].pattern); - if (res < 0) { - printf("error in regex pattern: %d\n", res); - continue; - } - printf("\ninput: %s\n", s[i].input); - - c_formatch (j, &re, s[i].input) { - c_forrange (k, cregex_captures(&re) + 1) - printf(" submatch %lld: %.*s\n", k, c_SV(j.match[k])); - } - } - cregex_drop(&re); -} diff --git a/misc/examples/regex_match.c b/misc/examples/regex_match.c deleted file mode 100644 index 11426d2d..00000000 --- a/misc/examples/regex_match.c +++ /dev/null @@ -1,37 +0,0 @@ -#define i_import -#include -#define i_implement -#include - -#define i_key float -#include - -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." - " Around 365.25 days a year, and 52 weeks in a year." - " Boltzmann const: 1.38064852E-23, is very small." - " Bohrradius is 5.29177210903e-11, and Avogadros number is 6.02214076e23."; - cregex re = {0}; - cstack_float vec = {0}; - - const char* pattern = "[+-]?([0-9]*\\.)?\\d+([Ee][+-]?\\d+)?"; - int res = cregex_compile(&re, pattern); - printf("%d: %s\n", res, pattern); - - // extract and convert all numbers in str to floats - c_formatch (i, &re, str) - cstack_float_push(&vec, (float)atof(i.match[0].str)); - - c_foreach (i, cstack_float, vec) - 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_STRIP); - printf("\n%s\n", cstr_str(&nums)); - - cstr_drop(&nums); - cregex_drop(&re); - cstack_float_drop(&vec); -} diff --git a/misc/examples/regex_replace.c b/misc/examples/regex_replace.c deleted file mode 100644 index f1ea2711..00000000 --- a/misc/examples/regex_replace.c +++ /dev/null @@ -1,57 +0,0 @@ -#define i_import -#include -#include - -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 - cstr_printf(out, "%04d", year + 10); - return true; - } - return false; -} - -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"; - cstr str = {0}; - cregex re = {0}; - - c_defer( - cregex_drop(&re), - cstr_drop(&str) - ){ - printf("INPUT: %s\n", input); - - /* replace with a fixed string, extended all-in-one call: */ - cstr_take(&str, cregex_replace_pattern(pattern, input, "YYYY-MM-DD")); - printf("fixed: %s\n", cstr_str(&str)); - - /* US date format, and add 10 years to dates: */ - cstr_take(&str, cregex_replace_pattern(pattern, input, "$1/$3/$2", 0, add_10_years, CREG_DEFAULT)); - printf("us+10: %s\n", cstr_str(&str)); - - /* Wrap first date inside []: */ - cstr_take(&str, cregex_replace_pattern(pattern, input, "[$0]")); - printf("brack: %s\n", cstr_str(&str)); - - /* Shows how to compile RE separately */ - re = cregex_from(pattern); - if (cregex_captures(&re) == 0) - continue; /* break c_defer */ - - /* European date format. */ - cstr_take(&str, cregex_replace(&re, input, "$3.$2.$1")); - 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_STRIP)); - printf("strip: %s\n", cstr_str(&str)); - - /* Wrap all words in ${} */ - cstr_take(&str, cregex_replace_pattern("[a-z]+", "52 apples and 31 mangoes", "$${$0}")); - printf("curly: %s\n", cstr_str(&str)); - } -} diff --git a/misc/examples/regularexpressions/regex1.c b/misc/examples/regularexpressions/regex1.c new file mode 100644 index 00000000..d8032358 --- /dev/null +++ b/misc/examples/regularexpressions/regex1.c @@ -0,0 +1,32 @@ +#define i_import +#include + +int main(int argc, char* argv[]) +{ + if (argc <= 1) { + printf("Usage: regex1 -i\n"); + return 0; + } + cstr input = {0}; + cregex float_expr = {0}; + + int res = cregex_compile(&float_expr, "^[+-]?[0-9]+((\\.[0-9]*)?|\\.[0-9]+)$"); + // Until "q" is given, ask for another number + if (res > 0) while (true) + { + printf("Enter a double precision number (q for quit): "); + cstr_getline(&input, stdin); + + // Exit when the user inputs q + if (cstr_equals(&input, "q")) + break; + + if (cregex_is_match(&float_expr, cstr_str(&input))) + printf("Input is a float\n"); + else + printf("Invalid input : Not a float\n"); + } + + cstr_drop(&input); + cregex_drop(&float_expr); +} diff --git a/misc/examples/regularexpressions/regex2.c b/misc/examples/regularexpressions/regex2.c new file mode 100644 index 00000000..a798b1a1 --- /dev/null +++ b/misc/examples/regularexpressions/regex2.c @@ -0,0 +1,34 @@ +#define i_import +#include + +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])", + "date: 2024-02-29 leapyear day, christmas eve is on 2022-12-24." + }, + {"(https?://|ftp://|www\\.)([0-9A-Za-z@:%_+~#=-]+\\.)+([a-z][a-z][a-z]?)(/[/0-9A-Za-z\\.@:%_+~#=\\?&-]*)?", + "https://en.cppreference.com/w/cpp/regex/regex_search" + }, + {"!((abc|123)+)!", "!123abcabc!"}, + {"(\\p{Alpha}+ )+(\\p{Nd}+)", "Großpackung süßigkeiten 199"}, + {"\\p{Han}+", "This is Han: 王明:那是杂志吗?"}, + }; + + cregex re = {0}; + c_forrange (i, c_arraylen(s)) + { + int res = cregex_compile(&re, s[i].pattern); + if (res < 0) { + printf("error in regex pattern: %d\n", res); + continue; + } + printf("\ninput: %s\n", s[i].input); + + c_formatch (j, &re, s[i].input) { + c_forrange (k, cregex_captures(&re) + 1) + printf(" submatch %lld: %.*s\n", k, c_SV(j.match[k])); + } + } + cregex_drop(&re); +} diff --git a/misc/examples/regularexpressions/regex_match.c b/misc/examples/regularexpressions/regex_match.c new file mode 100644 index 00000000..11426d2d --- /dev/null +++ b/misc/examples/regularexpressions/regex_match.c @@ -0,0 +1,37 @@ +#define i_import +#include +#define i_implement +#include + +#define i_key float +#include + +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." + " Around 365.25 days a year, and 52 weeks in a year." + " Boltzmann const: 1.38064852E-23, is very small." + " Bohrradius is 5.29177210903e-11, and Avogadros number is 6.02214076e23."; + cregex re = {0}; + cstack_float vec = {0}; + + const char* pattern = "[+-]?([0-9]*\\.)?\\d+([Ee][+-]?\\d+)?"; + int res = cregex_compile(&re, pattern); + printf("%d: %s\n", res, pattern); + + // extract and convert all numbers in str to floats + c_formatch (i, &re, str) + cstack_float_push(&vec, (float)atof(i.match[0].str)); + + c_foreach (i, cstack_float, vec) + 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_STRIP); + printf("\n%s\n", cstr_str(&nums)); + + cstr_drop(&nums); + cregex_drop(&re); + cstack_float_drop(&vec); +} diff --git a/misc/examples/regularexpressions/regex_replace.c b/misc/examples/regularexpressions/regex_replace.c new file mode 100644 index 00000000..f1ea2711 --- /dev/null +++ b/misc/examples/regularexpressions/regex_replace.c @@ -0,0 +1,57 @@ +#define i_import +#include +#include + +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 + cstr_printf(out, "%04d", year + 10); + return true; + } + return false; +} + +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"; + cstr str = {0}; + cregex re = {0}; + + c_defer( + cregex_drop(&re), + cstr_drop(&str) + ){ + printf("INPUT: %s\n", input); + + /* replace with a fixed string, extended all-in-one call: */ + cstr_take(&str, cregex_replace_pattern(pattern, input, "YYYY-MM-DD")); + printf("fixed: %s\n", cstr_str(&str)); + + /* US date format, and add 10 years to dates: */ + cstr_take(&str, cregex_replace_pattern(pattern, input, "$1/$3/$2", 0, add_10_years, CREG_DEFAULT)); + printf("us+10: %s\n", cstr_str(&str)); + + /* Wrap first date inside []: */ + cstr_take(&str, cregex_replace_pattern(pattern, input, "[$0]")); + printf("brack: %s\n", cstr_str(&str)); + + /* Shows how to compile RE separately */ + re = cregex_from(pattern); + if (cregex_captures(&re) == 0) + continue; /* break c_defer */ + + /* European date format. */ + cstr_take(&str, cregex_replace(&re, input, "$3.$2.$1")); + 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_STRIP)); + printf("strip: %s\n", cstr_str(&str)); + + /* Wrap all words in ${} */ + cstr_take(&str, cregex_replace_pattern("[a-z]+", "52 apples and 31 mangoes", "$${$0}")); + printf("curly: %s\n", cstr_str(&str)); + } +} diff --git a/misc/examples/replace.c b/misc/examples/replace.c deleted file mode 100644 index 59a56bf7..00000000 --- a/misc/examples/replace.c +++ /dev/null @@ -1,36 +0,0 @@ -#define i_implement -#include - -int main(void) -{ - const char *base = "this is a test string."; - const char *s2 = "n example"; - const char *s3 = "sample phrase"; - - // replace signatures used in the same order as described above: - - // Ustring positions: 0123456789*123456789*12345 - cstr s = cstr_from(base); // "this is a test string." - cstr m = cstr_clone(s); - - cstr_append(&m, cstr_str(&m)); - cstr_append(&m, cstr_str(&m)); - printf("%s\n", cstr_str(&m)); - - cstr_replace_at(&s, 9, 5, s2); // "this is an example string." (1) - printf("(1) %s\n", cstr_str(&s)); - - cstr_replace_at_sv(&s, 19, 6, c_sv(s3+7, 6)); // "this is an example phrase." (2) - printf("(2) %s\n", cstr_str(&s)); - - cstr_replace_at(&s, 8, 10, "just a"); // "this is just a phrase." (3) - printf("(3) %s\n", cstr_str(&s)); - - cstr_replace_at_sv(&s, 8, 6, c_sv("a shorty", 7)); // "this is a short phrase." (4) - printf("(4) %s\n", cstr_str(&s)); - - cstr_replace_at(&s, 22, 1, "!!!"); // "this is a short phrase!!!" (5) - printf("(5) %s\n", cstr_str(&s)); - - c_drop(cstr, &s, &m); -} diff --git a/misc/examples/scheduler.c b/misc/examples/scheduler.c deleted file mode 100644 index 38defd0f..00000000 --- a/misc/examples/scheduler.c +++ /dev/null @@ -1,74 +0,0 @@ -// https://www.youtube.com/watch?v=8sEe-4tig_A -#include -#include - -struct Task { - int (*fn)(struct Task*); - int cco_state; - struct Scheduler* sched; -}; - -#define i_type Scheduler -#define i_key struct Task -#include - -static bool schedule(Scheduler* sched) -{ - struct Task task = *Scheduler_front(sched); - Scheduler_pop(sched); - - if (!cco_done(&task)) - task.fn(&task); - - return !Scheduler_empty(sched); -} - -static int push_task(const struct Task* task) -{ - Scheduler_push(task->sched, *task); - return CCO_YIELD; -} - - -static int taskA(struct Task* task) -{ - cco_routine(task) { - puts("Hello, from task A"); - cco_yield_v(push_task(task)); - puts("A is back doing work"); - cco_yield_v(push_task(task)); - puts("A is back doing more work"); - cco_yield_v(push_task(task)); - puts("A is back doing even more work"); - } - return 0; -} - -static int taskB(struct Task* task) -{ - cco_routine(task) { - puts("Hello, from task B"); - cco_yield_v(push_task(task)); - puts("B is back doing work"); - cco_yield_v(push_task(task)); - puts("B is back doing more work"); - } - return 0; -} - -void Use(void) -{ - Scheduler scheduler = c_init(Scheduler, { - {.fn=taskA, .sched=&scheduler}, - {.fn=taskB, .sched=&scheduler}, - }); - - while (schedule(&scheduler)) {} - - Scheduler_drop(&scheduler); -} - -int main(void) -{ - Use(); -} diff --git a/misc/examples/shape.c b/misc/examples/shape.c deleted file mode 100644 index bd4bdd5a..00000000 --- a/misc/examples/shape.c +++ /dev/null @@ -1,158 +0,0 @@ -// Demo of typesafe polymorphism in C99, using STC. - -#include -#include -#include - -#define DYN_CAST(T, s) \ - (&T##_api == (s)->api ? (T*)(s) : (T*)0) - -// Shape definition -// ============================================================ - -typedef struct { - float x, y; -} Point; - -typedef struct Shape Shape; - -struct ShapeAPI { - void (*drop)(Shape*); - void (*draw)(const Shape*); -}; - -struct Shape { - struct ShapeAPI* api; - uint32_t color; - uint16_t style; - uint8_t thickness; - uint8_t hardness; -}; - -void Shape_drop(Shape* shape) -{ - printf("shape destructed\n"); -} - -void Shape_delete(Shape* shape) -{ - if (shape) { - shape->api->drop(shape); - c_free(shape); - } -} - -// Triangle implementation -// ============================================================ - -typedef struct { - Shape shape; - Point p[3]; -} Triangle; - -extern struct ShapeAPI Triangle_api; - - -Triangle Triangle_from(Point a, Point b, Point c) { - Triangle t = {{&Triangle_api}, {a, b, c}}; - return t; -} - -static void Triangle_draw(const Shape* shape) -{ - const Triangle* self = DYN_CAST(Triangle, shape); - printf("Triangle : (%g,%g), (%g,%g), (%g,%g)\n", - (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 = { - .drop = Shape_drop, - .draw = Triangle_draw, -}; - -// Polygon implementation -// ============================================================ - -#define i_type PointVec -#define i_key Point -#include - -typedef struct { - Shape shape; - PointVec points; -} Polygon; - -extern struct ShapeAPI Polygon_api; - - -Polygon Polygon_init(void) { - Polygon p = {{&Polygon_api}, {0}}; - return p; -} - -void Polygon_addPoint(Polygon* self, Point p) -{ - PointVec_push(&self->points, p); -} - -static void Polygon_drop(Shape* shape) -{ - Polygon* self = DYN_CAST(Polygon, shape); - printf("poly destructed\n"); - PointVec_drop(&self->points); -} - -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)", (double)i.ref->x, (double)i.ref->y); - puts(""); -} - -struct ShapeAPI Polygon_api = { - .drop = Polygon_drop, - .draw = Polygon_draw, -}; - -// Test -// ============================================================ - -#define i_type Shapes -#define i_key Shape* -#define i_keydrop(x) Shape_delete(*x) -#define i_no_clone -#include - -void testShape(const Shape* shape) -{ - shape->api->draw(shape); -} - - -int main(void) -{ - Shapes shapes = {0}; - - 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()); - - c_forlist (i, Point, {{50, 72}, {123, 73}, {127, 201}, {828, 333}}) - Polygon_addPoint(pol1, *i.ref); - - c_forlist (i, Point, {{5, 7}, {12, 7}, {12, 20}, {82, 33}, {17, 56}}) - Polygon_addPoint(pol2, *i.ref); - - Shapes_push(&shapes, &tri1->shape); - Shapes_push(&shapes, &pol1->shape); - Shapes_push(&shapes, &pol2->shape); - - c_foreach (i, Shapes, shapes) - testShape(*i.ref); - - Shapes_drop(&shapes); -} diff --git a/misc/examples/shape.cpp b/misc/examples/shape.cpp deleted file mode 100644 index ea1f53d2..00000000 --- a/misc/examples/shape.cpp +++ /dev/null @@ -1,122 +0,0 @@ -// Demo of polymorphism in C++ - -#include -#include -#include - -// Shape definition -// ============================================================ - -struct Point { - float x, y; -}; - -std::ostream& operator<<(std::ostream& os, const Point& p) { - os << " (" << p.x << "," << p.y << ")"; - return os; -} - -struct Shape { - virtual ~Shape(); - virtual void draw() const = 0; - - uint32_t color; - uint16_t style; - uint8_t thickness; - uint8_t hardness; -}; - -Shape::~Shape() -{ - std::cout << "base destructed" << std::endl; -} - -// Triangle implementation -// ============================================================ - -struct Triangle : public Shape -{ - Triangle(Point a, Point b, Point c); - void draw() const override; - - private: Point p[3]; -}; - - -Triangle::Triangle(Point a, Point b, Point c) - : p{a, b, c} {} - -void Triangle::draw() const -{ - std::cout << "Triangle :" - << p[0] << p[1] << p[2] - << std::endl; -} - - -// Polygon implementation -// ============================================================ - - -struct Polygon : public Shape -{ - ~Polygon(); - void draw() const override; - void addPoint(const Point& p); - - private: std::vector points; -}; - - -void Polygon::addPoint(const Point& p) -{ - points.push_back(p); -} - -Polygon::~Polygon() -{ - std::cout << "poly destructed" << std::endl; -} - -void Polygon::draw() const -{ - std::cout << "Polygon :"; - for (auto& p : points) - std::cout << p ; - std::cout << std::endl; -} - - -// Test -// ============================================================ - -void testShape(const Shape* shape) -{ - shape->draw(); -} - -#include - -int main(void) -{ - std::vector> shapes; - - auto tri1 = std::make_unique(Point{5, 7}, Point{12, 7}, Point{12, 20}); - auto pol1 = std::make_unique(); - auto pol2 = std::make_unique(); - - for (auto& p: std::array - {{{50, 72}, {123, 73}, {127, 201}, {828, 333}}}) - pol1->addPoint(p); - - for (auto& p: std::array - {{{5, 7}, {12, 7}, {12, 20}, {82, 33}, {17, 56}}}) - pol2->addPoint(p); - - shapes.push_back(std::move(tri1)); - shapes.push_back(std::move(pol1)); - shapes.push_back(std::move(pol2)); - - for (auto& shape: shapes) - testShape(shape.get()); -} diff --git a/misc/examples/sidebyside.cpp b/misc/examples/sidebyside.cpp deleted file mode 100644 index 9414b691..00000000 --- a/misc/examples/sidebyside.cpp +++ /dev/null @@ -1,57 +0,0 @@ -#include -#include -#include -#include - -#define i_type IIMap -#define i_key int -#define i_val int -#include - -#define i_type SIMap -#define i_key_str -#define i_val int -#include - -int main(void) { - { - std::map 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 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/smartpointers/arc_containers.c b/misc/examples/smartpointers/arc_containers.c new file mode 100644 index 00000000..2fb04c56 --- /dev/null +++ b/misc/examples/smartpointers/arc_containers.c @@ -0,0 +1,81 @@ +// Create a stack and a list of shared pointers to maps, +// and demonstrate sharing and cloning of maps. +#define i_implement +#include +#include +#define i_type Map +#define i_key_str // strings +#define i_val int +#define i_keydrop(p) (printf("drop name: %s\n", cstr_str(p)), cstr_drop(p)) +#include + +#define i_type Arc // (atomic) ref. counted type +#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 +#include + +#define i_type Stack +#define i_keyboxed Arc // define i_keyboxed for carc/cbox value (not i_key) +#include + +#define i_type List +#define i_keyboxed Arc // as above +#include + +int main(void) +{ + Stack stack = {0}; + List list = {0}; + c_defer( + Stack_drop(&stack), + List_drop(&list) + ){ + // POPULATE stack with shared pointers to Maps: + Map *map; + map = Stack_push(&stack, Arc_from(Map_init()))->get; + Map_emplace(map, "Joey", 1990); + Map_emplace(map, "Mary", 1995); + Map_emplace(map, "Joanna", 1992); + + map = Stack_push(&stack, Arc_from(Map_init()))->get; + Map_emplace(map, "Rosanna", 2001); + Map_emplace(map, "Brad", 1999); + Map_emplace(map, "Jack", 1980); + + // POPULATE list: + map = List_push_back(&list, Arc_from(Map_init()))->get; + Map_emplace(map, "Steve", 1979); + Map_emplace(map, "Rick", 1974); + Map_emplace(map, "Tracy", 2003); + + // Share two Maps from the stack with the list using emplace (clone the carc): + List_push_back(&list, Arc_clone(stack.data[0])); + List_push_back(&list, Arc_clone(stack.data[1])); + + // Clone (deep copy) a Map from the stack to the list + // List will contain two shared and two unshared maps. + map = List_push_back(&list, Arc_from(Map_clone(*stack.data[1].get)))->get; + + // Add one more element to the cloned map: + Map_emplace_or_assign(map, "CLONED", 2021); + + // Add one more element to the shared map: + Map_emplace_or_assign(stack.data[1].get, "SHARED", 2021); + + puts("STACKS"); + c_foreach (i, Stack, stack) { + c_forpair (name, year, Map, *i.ref->get) + printf(" %s:%d", cstr_str(_.name), *_.year); + puts(""); + } + + puts("LIST"); + c_foreach (i, List, list) { + c_forpair (name, year, Map, *i.ref->get) + printf(" %s:%d", cstr_str(_.name), *_.year); + puts(""); + } + } +} diff --git a/misc/examples/smartpointers/arc_demo.c b/misc/examples/smartpointers/arc_demo.c new file mode 100644 index 00000000..929a48a1 --- /dev/null +++ b/misc/examples/smartpointers/arc_demo.c @@ -0,0 +1,62 @@ +#include +#include + +void int_drop(int* x) { + printf("drop: %d\n", *x); +} + +// carc implements its own clone method using reference counting, +// 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_key int +#define i_keydrop int_drop // optional, just to display the elements destroyed +#define i_cmp_native // use int comparison (x < y, x == y). +#include // Arc + +#define i_keyboxed Arc // note: use i_keyboxed instead of i_key for carc/cbox elements +#include // csset_Arc (like: std::set>) + +#define i_keyboxed Arc // note: as above. +#include // cvec_Arc (like: std::vector>) + +int main(void) +{ + const int years[] = {2021, 2012, 2022, 2015}; + + cvec_Arc vec = {0}; + 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) + printf(" %d", *i.ref->get); + puts(""); + + // add odd numbers from vec to set + csset_Arc set = {0}; + c_foreach (i, cvec_Arc, vec) + if (*i.ref->get & 1) + csset_Arc_insert(&set, Arc_clone(*i.ref)); // copy shared pointer => increments counter. + + // erase the two last elements in vec + cvec_Arc_pop_back(&vec); + cvec_Arc_pop_back(&vec); + + printf("vec:"); + c_foreach (i, cvec_Arc, vec) printf(" %d", *i.ref->get); + + printf("\nset:"); + c_foreach (i, csset_Arc, set) printf(" %d", *i.ref->get); + + Arc p = Arc_clone(vec.data[0]); + printf("\n%d is now owned by %ld objects\n", *p.get, *p.use_count); + + Arc_drop(&p); + cvec_Arc_drop(&vec); + csset_Arc_drop(&set); +} diff --git a/misc/examples/smartpointers/arcvec_erase.c b/misc/examples/smartpointers/arcvec_erase.c new file mode 100644 index 00000000..ba54c1c7 --- /dev/null +++ b/misc/examples/smartpointers/arcvec_erase.c @@ -0,0 +1,50 @@ +#include + +void show_drop(int* x) { printf("drop: %d\n", *x); } + +#define i_type Arc +#define i_key int +#define i_keydrop show_drop +#define i_cmp_native // enable sort/search for int type +#include // Shared pointer to int + +#define i_type Vec +#define i_keyboxed Arc +#include // Vec: cvec + + +int main(void) +{ + 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])); + + printf("vec before erase :"); + c_foreach (i, Vec, vec) + printf(" %d", *i.ref->get); + + printf("\nerase vec.data[2]; or first matching value depending on compare.\n"); + Vec_iter it; + it = Vec_find(&vec, *vec.data[2].get); + if (it.ref) + Vec_erase_at(&vec, it); + + int year = 2015; + it = Vec_find(&vec, year); // Ok as tmp only. + if (it.ref) + Vec_erase_at(&vec, it); + + printf("vec after erase :"); + c_foreach (i, Vec, vec) + printf(" %d", *i.ref->get); + + Vec_sort(&vec); + printf("\nvec after sort :"); + c_foreach (i, Vec, vec) + printf(" %d", *i.ref->get); + + puts("\nDone"); + Vec_drop(&vec); +} diff --git a/misc/examples/smartpointers/box.c b/misc/examples/smartpointers/box.c new file mode 100644 index 00000000..94d126c0 --- /dev/null +++ b/misc/examples/smartpointers/box.c @@ -0,0 +1,69 @@ +/* cbox: heap allocated boxed type */ +#define i_implement +#include + +typedef struct { cstr name, last; } Person; + +Person Person_make(const char* name, const char* last) { + return c_LITERAL(Person){.name = cstr_from(name), .last = cstr_from(last)}; +} + +uint64_t Person_hash(const Person* a) { + return cstr_hash(&a->name) ^ cstr_hash(&a->last); +} + +int Person_cmp(const Person* a, const Person* b) { + int c = cstr_cmp(&a->name, &b->name); + return c ? c : cstr_cmp(&a->last, &b->last); +} + +Person Person_clone(Person p) { + p.name = cstr_clone(p.name); + p.last = cstr_clone(p.last); + return p; +} + +void Person_drop(Person* p) { + printf("drop: %s %s\n", cstr_str(&p->name), cstr_str(&p->last)); + c_drop(cstr, &p->name, &p->last); +} + +#define i_type PBox +#define i_keyclass Person // "class" binds _cmp, _clone, _drop functions. +#include + +#define i_type Persons +#define i_keyboxed PBox // "arcbox" informs that PBox is a smart pointer. +#include + +int main(void) +{ + Persons vec = {0}; + PBox p = PBox_from(Person_make("Laura", "Palmer")); + PBox q = PBox_clone(p); + cstr_assign(&q.get->name, "Leland"); + + printf("orig: %s %s\n", cstr_str(&p.get->name), cstr_str(&p.get->last)); + printf("copy: %s %s\n", cstr_str(&q.get->name), cstr_str(&q.get->last)); + + Persons_emplace(&vec, Person_make("Dale", "Cooper")); + Persons_emplace(&vec, Person_make("Audrey", "Home")); + + // NB! Clone/share p and q in the Persons container. + Persons_push(&vec, PBox_clone(p)); + Persons_push(&vec, PBox_clone(q)); + + c_foreach (i, Persons, vec) + printf("%s %s\n", cstr_str(&i.ref->get->name), cstr_str(&i.ref->get->last)); + puts(""); + + // Look-up Audrey! Create a temporary Person for lookup. + Person a = Person_make("Audrey", "Home"); + const PBox *v = Persons_get(&vec, a); // lookup + if (v) printf("found: %s %s\n", cstr_str(&v->get->name), cstr_str(&v->get->last)); + + Person_drop(&a); + PBox_drop(&p); + PBox_drop(&q); + Persons_drop(&vec); +} diff --git a/misc/examples/smartpointers/box2.c b/misc/examples/smartpointers/box2.c new file mode 100644 index 00000000..eaab1c47 --- /dev/null +++ b/misc/examples/smartpointers/box2.c @@ -0,0 +1,82 @@ +// example: https://doc.rust-lang.org/rust-by-example/std/box.html +#include + +typedef struct { + double x; + double y; +} Point; + +// A Rectangle can be specified by where its top left and bottom right +// corners are in space +typedef struct { + Point top_left; + Point bottom_right; +} Rectangle; + +#define i_key Point +#include // cbox_Point + +#define i_key Rectangle +#include // cbox_Rectangle + +// Box in box: +#define i_type BoxBoxPoint +#define i_keyboxed cbox_Point // NB: use i_keyboxed when value is a cbox or carc! +#define i_no_cmp +#include // BoxBoxPoint + +Point origin(void) { + 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(c_LITERAL(Point){ .x=1.0, .y=2.0 }); +} + + +int main(void) { + // Stack allocated variables + Point point = origin(); + Rectangle rectangle = { + .top_left = origin(), + .bottom_right = { .x=3.0, .y=-4.0 } + }; + + // Heap allocated rectangle + cbox_Rectangle boxed_rectangle = cbox_Rectangle_make(c_LITERAL(Rectangle){ + .top_left = origin(), + .bottom_right = { .x=3.0, .y=-4.0 } + }); + // The output of functions can be boxed + cbox_Point boxed_point = cbox_Point_make(origin()); + + // Can use from(raw) and toraw instead: + BoxBoxPoint box_in_a_box = BoxBoxPoint_from(origin()); + + c_defer( + BoxBoxPoint_drop(&box_in_a_box), + cbox_Point_drop(&boxed_point), + cbox_Rectangle_drop(&boxed_rectangle) + ){ + printf("box_in_a_box: x = %g\n", BoxBoxPoint_toraw(&box_in_a_box).x); + + printf("Point occupies %d bytes on the stack\n", + (int)sizeof(point)); + printf("Rectangle occupies %d bytes on the stack\n", + (int)sizeof(rectangle)); + + // box size == pointer size + printf("Boxed point occupies %d bytes on the stack\n", + (int)sizeof(boxed_point)); + printf("Boxed rectangle occupies %d bytes on the stack\n", + (int)sizeof(boxed_rectangle)); + printf("Boxed box occupies %d bytes on the stack\n", + (int)sizeof(box_in_a_box)); + + // Copy the data contained in `boxed_point` into `unboxed_point` + Point unboxed_point = *boxed_point.get; + printf("Unboxed point occupies %d bytes on the stack\n", + (int)sizeof(unboxed_point)); + } +} diff --git a/misc/examples/smartpointers/music_arc.c b/misc/examples/smartpointers/music_arc.c new file mode 100644 index 00000000..16111b0b --- /dev/null +++ b/misc/examples/smartpointers/music_arc.c @@ -0,0 +1,67 @@ +// 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 + +typedef struct +{ + cstr artist; + cstr title; +} Song; + +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 c_LITERAL(Song){cstr_from(artist), cstr_from(title)}; } + +void Song_drop(Song* s) { + printf("drop: %s\n", cstr_str(&s->title)); + c_drop(cstr, &s->artist, &s->title); +} + +// Define the shared pointer: +#define i_type SongArc +#define i_keyclass Song +#define i_no_hash // no hash fn for Song, fallback hash pointer to Song. +#include + +// ... and a vector of them +#define i_type SongVec +#define i_keyboxed SongArc // use i_keyboxed on carc / cbox (instead of i_key) +#include + +void example3(void) +{ + SongVec vec1 = c_init(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 vec2 = {0}; + // Share all entries in vec with vec2, except Bob Dylan. + c_foreach (s, SongVec, vec1) + if (!cstr_equals(&s.ref->get->artist, "Bob Dylan")) + SongVec_push(&vec2, SongArc_clone(*s.ref)); + + // 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")); + + // We now have two vectors with some shared, some unique entries. + c_forlist (i, SongVec, {vec1, vec2}) { + puts("VEC:"); + c_foreach (s, SongVec, *i.ref) + printf(" %s - %s, REFS: %ld\n", cstr_str(&s.ref->get->artist), + cstr_str(&s.ref->get->title), + *s.ref->use_count); + } + c_drop(SongVec, &vec1, &vec2); +} + +int main(void) +{ + example3(); +} diff --git a/misc/examples/smartpointers/new_sptr.c b/misc/examples/smartpointers/new_sptr.c new file mode 100644 index 00000000..3c6fa16c --- /dev/null +++ b/misc/examples/smartpointers/new_sptr.c @@ -0,0 +1,75 @@ +#define i_implement +#include + +typedef struct { cstr name, last; } Person; +Person Person_make(const char* name, const char* last); +Person Person_clone(Person p); +void Person_drop(Person* p); +int Person_cmp(const Person* a, const Person* b); +uint64_t Person_hash(const Person* p); + +#define i_type PersonArc +#define i_keyclass Person // "class" assume _clone, _drop, _cmp, _hash is defined. +#include + +#define i_type IPtr +#define i_key int +#define i_keydrop(x) printf("drop: %d\n", *x) +#define i_cmp_native +#include + +#define i_type IPStack +#define i_keyboxed IPtr +#include + +#define i_type PASet +#define i_keyboxed PersonArc +#include + + +Person Person_make(const char* name, const char* last) { + Person p = {.name = cstr_from(name), .last = cstr_from(last)}; + return p; +} + +int Person_cmp(const Person* a, const Person* b) { + return cstr_cmp(&a->name, &b->name); +} + +uint64_t Person_hash(const Person* p) { + return cstr_hash(&p->name); +} + +Person Person_clone(Person p) { + p.name = cstr_clone(p.name), p.last = cstr_clone(p.last); + return p; +} + +void Person_drop(Person* p) { + printf("drop: %s %s\n", cstr_str(&p->name), cstr_str(&p->last)); + c_drop(cstr, &p->name, &p->last); +} + + +int main(void) { + puts("Ex1"); + PersonArc p = PersonArc_from(Person_make("John", "Smiths")); + PersonArc q = PersonArc_clone(p); // share + PersonArc r = PersonArc_clone(p); + PersonArc s = PersonArc_from(Person_clone(*p.get)); // deep copy + printf("%s %s: refs %ld\n", cstr_str(&p.get->name), cstr_str(&p.get->last), *p.use_count); + c_drop(PersonArc, &p, &q, &r, &s); + + puts("Ex2"); + IPStack vec = {0}; + IPStack_push(&vec, IPtr_from(10)); + IPStack_push(&vec, IPtr_from(20)); + IPStack_emplace(&vec, 30); // same as IPStack_push(&vec, IPtr_from(30)); + IPStack_push(&vec, IPtr_clone(*IPStack_back(&vec))); + IPStack_push(&vec, IPtr_clone(*IPStack_front(&vec))); + + c_foreach (i, IPStack, vec) + printf(" (%d: refs %ld)", *i.ref->get, *i.ref->use_count); + puts(""); + IPStack_drop(&vec); +} diff --git a/misc/examples/smartpointers/person_arc.c b/misc/examples/smartpointers/person_arc.c new file mode 100644 index 00000000..38c883a7 --- /dev/null +++ b/misc/examples/smartpointers/person_arc.c @@ -0,0 +1,77 @@ +/* cbox: heap allocated boxed type */ +#define i_implement +#include + +typedef struct { cstr name, last; } Person; + +Person Person_make(const char* name, const char* last) { + Person p = {.name = cstr_from(name), .last = cstr_from(last)}; + return p; +} + +int Person_cmp(const Person* a, const Person* b) { + int c = cstr_cmp(&a->name, &b->name); + return c ? c : cstr_cmp(&a->last, &b->last); +} + +uint64_t Person_hash(const Person* a) { + return cstr_hash(&a->name) ^ cstr_hash(&a->last); +} + +Person Person_clone(Person p) { + p.name = cstr_clone(p.name); + p.last = cstr_clone(p.last); + return p; +} + +void Person_drop(Person* p) { + printf("drop: %s %s\n", cstr_str(&p->name), cstr_str(&p->last)); + c_drop(cstr, &p->name, &p->last); +} + +#define i_type PSPtr +#define i_keyclass Person // ensure Person_drop +#define i_cmp Person_cmp // specify object cmp, instead of ptr cmp for arc. +#include + +#define i_type Persons +#define i_keyboxed PSPtr // binds PSPtr_cmp, PSPtr_drop... +#include + + +int main(void) +{ + PSPtr p = PSPtr_from(Person_make("Laura", "Palmer")); + PSPtr q = PSPtr_from(Person_clone(*p.get)); // deep copy + Persons vec = {0}; + + c_defer( + PSPtr_drop(&p), + PSPtr_drop(&q), + Persons_drop(&vec) + ){ + cstr_assign(&q.get->name, "Leland"); + + printf("orig: %s %s\n", cstr_str(&p.get->name), cstr_str(&p.get->last)); + printf("copy: %s %s\n", cstr_str(&q.get->name), cstr_str(&q.get->last)); + + // Use Persons_emplace to implicitly call PSPtr_make on the argument. + // No need to do: Persons_push(&vec, PSPtr_make(Person_make("Audrey", "Home"))); + Persons_emplace(&vec, Person_make("Audrey", "Home")); + Persons_emplace(&vec, Person_make("Dale", "Cooper")); + + // Clone/share p and q to the vector + c_forlist (i, PSPtr, {p, q}) + Persons_push(&vec, PSPtr_clone(*i.ref)); + + c_foreach (i, Persons, vec) + printf("%s %s\n", cstr_str(&i.ref->get->name), cstr_str(&i.ref->get->last)); + puts(""); + + // Look-up Audrey! + Person a = Person_make("Audrey", "Home"); + const PSPtr *v = Persons_get(&vec, a); + if (v) printf("found: %s %s\n", cstr_str(&v->get->name), cstr_str(&v->get->last)); + Person_drop(&a); + } +} diff --git a/misc/examples/smartpointers/rawptr_elements.c b/misc/examples/smartpointers/rawptr_elements.c new file mode 100644 index 00000000..694ce12e --- /dev/null +++ b/misc/examples/smartpointers/rawptr_elements.c @@ -0,0 +1,59 @@ +#include +#include +#define i_implement +#include + +// 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 + +// Alternatively, using cbox: +#define i_type IBox +#define i_key long +#include // unique_ptr 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 + +int main(void) +{ + // 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/sorted_map.c b/misc/examples/sorted_map.c deleted file mode 100644 index 89381554..00000000 --- a/misc/examples/sorted_map.c +++ /dev/null @@ -1,67 +0,0 @@ -// https://iq.opengenus.org/containers-cpp-stl/ - -#include -#define i_key int -#define i_val int -#include - -int main(void) -{ - - // empty map containers - csmap_int gquiz1 = {0}, gquiz2 = {0}; - c_defer( - csmap_int_drop(&gquiz1), - csmap_int_drop(&gquiz2) - ){ - // insert elements in random order - csmap_int_insert(&gquiz1, 2, 30); - csmap_int_insert(&gquiz1, 4, 20); - csmap_int_insert(&gquiz1, 7, 10); - csmap_int_insert(&gquiz1, 5, 50); - csmap_int_insert(&gquiz1, 3, 60); - csmap_int_insert(&gquiz1, 1, 40); - csmap_int_insert(&gquiz1, 6, 50); - - // printing map gquiz1 - printf("\nThe map gquiz1 is :\n\tKEY\tELEMENT\n"); - c_foreach (itr, csmap_int, gquiz1) - printf("\t%d\t%d\n", itr.ref->first, itr.ref->second); - printf("\n"); - - // assigning the elements from gquiz1 to gquiz2 - c_foreach (i, csmap_int, gquiz1) - csmap_int_insert(&gquiz2, i.ref->first, i.ref->second); - - // print all elements of the map gquiz2 - printf("\nThe map gquiz2 is :\n\tKEY\tELEMENT\n"); - c_foreach (itr, csmap_int, gquiz2) - printf("\t%d\t%d\n", itr.ref->first, itr.ref->second); - printf("\n"); - - // remove all elements up to element with key=3 in gquiz2 - printf("\ngquiz2 after removal of elements less than key=3 :\n"); - printf("\tKEY\tELEMENT\n"); - csmap_int_erase_range(&gquiz2, csmap_int_begin(&gquiz2), - csmap_int_find(&gquiz2, 3)); - c_foreach (itr, csmap_int, gquiz2) - printf("\t%d\t%d\n", itr.ref->first, itr.ref->second); - printf("\n"); - - // remove all elements with key = 4 - int num = csmap_int_erase(&gquiz2, 4); - printf("\ngquiz2.erase(4) : %d removed\n", num); - printf("\tKEY\tELEMENT\n"); - c_foreach (itr, csmap_int, gquiz2) - printf("\t%d\t%d\n", itr.ref->first, itr.ref->second); - printf("\n"); - - // lower bound and upper bound for map gquiz1 key = 5 - printf("gquiz1.lower_bound(5) : "); - printf("\tKEY = %d\t", csmap_int_lower_bound(&gquiz1, 5).ref->first); - printf("\tELEMENT = %d\n", csmap_int_lower_bound(&gquiz1, 5).ref->second); - printf("gquiz1.upper_bound(5) : "); - printf("\tKEY = %d\t", csmap_int_lower_bound(&gquiz1, 5+1).ref->first); - printf("\tELEMENT = %d\n", csmap_int_lower_bound(&gquiz1, 5+1).ref->second); - } -} diff --git a/misc/examples/sortedmaps/csmap_erase.c b/misc/examples/sortedmaps/csmap_erase.c new file mode 100644 index 00000000..8d4eeae3 --- /dev/null +++ b/misc/examples/sortedmaps/csmap_erase.c @@ -0,0 +1,82 @@ +// 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 +#include + +#define i_key int +#define i_val_str +#define i_type mymap +#include + +void printmap(mymap m) +{ + c_foreach (elem, mymap, m) + printf(" [%d, %s]", elem.ref->first, cstr_str(&elem.ref->second)); + printf("\nsize() == %" c_ZI "\n\n", mymap_size(&m)); +} + +int main(void) +{ + mymap m1 = {0}; + + // Fill in some data to test with, one at a time + mymap_insert(&m1, 1, cstr_lit("A")); + mymap_insert(&m1, 2, cstr_lit("B")); + mymap_insert(&m1, 3, cstr_lit("C")); + mymap_insert(&m1, 4, cstr_lit("D")); + mymap_insert(&m1, 5, cstr_lit("E")); + + puts("Starting data of map m1 is:"); + printmap(m1); + // The 1st member function removes an element at a given position + mymap_erase_at(&m1, mymap_advance(mymap_begin(&m1), 1)); + puts("After the 2nd element is deleted, the map m1 is:"); + printmap(m1); + + // Fill in some data to test with + mymap m2 = c_init(mymap, { + {10, "Bob"}, + {11, "Rob"}, + {12, "Robert"}, + {13, "Bert"}, + {14, "Bobby"}, + }); + + puts("Starting data of map m2 is:"); + printmap(m2); + mymap_iter it1 = mymap_advance(mymap_begin(&m2), 1); + mymap_iter it2 = mymap_find(&m2, mymap_back(&m2)->first); + + puts("to remove:"); + c_foreach (i, mymap, it1, it2) + printf(" [%d, %s]", i.ref->first, cstr_str(&i.ref->second)); + puts(""); + // The 2nd member function removes elements + // in the range [First, Last) + mymap_erase_range(&m2, it1, it2); + puts("After the middle elements are deleted, the map m2 is:"); + printmap(m2); + + mymap m3 = {0}; + + // Fill in some data to test with, one at a time, using emplace + mymap_emplace(&m3, 1, "red"); + mymap_emplace(&m3, 2, "yellow"); + mymap_emplace(&m3, 3, "blue"); + mymap_emplace(&m3, 4, "green"); + mymap_emplace(&m3, 5, "orange"); + mymap_emplace(&m3, 6, "purple"); + mymap_emplace(&m3, 7, "pink"); + + puts("Starting data of map m3 is:"); + printmap(m3); + // The 3rd member function removes elements with a given Key + int count = mymap_erase(&m3, 2); + // The 3rd member function also returns the number of elements removed + printf("The number of elements removed from m3 is: %d\n", count); + puts("After the element with a key of 2 is deleted, the map m3 is:"); + printmap(m3); + + c_drop(mymap, &m1, &m2, &m3); +} diff --git a/misc/examples/sortedmaps/csmap_find.c b/misc/examples/sortedmaps/csmap_find.c new file mode 100644 index 00000000..c392338d --- /dev/null +++ b/misc/examples/sortedmaps/csmap_find.c @@ -0,0 +1,73 @@ +// 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 + +#define i_key int +#define i_val_str +#define i_tag istr +#include + +#define i_key csmap_istr_raw +#define i_tag istr +#include + +void print_elem(csmap_istr_raw p) { + printf("(%d, %s) ", p.first, p.second); +} + +#define using_print_collection(CX) \ + void print_collection_##CX(const CX* t) { \ + printf("%" c_ZI " elements: ", CX##_size(t)); \ + \ + c_foreach (p, CX, *t) { \ + print_elem(CX##_value_toraw(p.ref)); \ + } \ + puts(""); \ + } + +using_print_collection(csmap_istr) +using_print_collection(cvec_istr) + +void findit(csmap_istr c, csmap_istr_key val) +{ + printf("Trying find() on value %d\n", val); + csmap_istr_iter result = csmap_istr_find(&c, val); // prefer contains() or get() + if (result.ref) { + printf("Element found: "); print_elem(csmap_istr_value_toraw(result.ref)); puts(""); + } else { + puts("Element not found."); + } +} + +int main(void) +{ + 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, 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); + + c_foreach (i, cvec_istr, cvec_istr_begin(&v), cvec_istr_end(&v)) + csmap_istr_emplace(&m1, i.ref->first, i.ref->second); + + puts("The modified map m1 is (key, value):"); + print_collection_csmap_istr(&m1); + puts(""); + findit(m1, 45); + findit(m1, 6); + + csmap_istr_drop(&m1); + cvec_istr_drop(&v); +} diff --git a/misc/examples/sortedmaps/csmap_insert.c b/misc/examples/sortedmaps/csmap_insert.c new file mode 100644 index 00000000..c9f02891 --- /dev/null +++ b/misc/examples/sortedmaps/csmap_insert.c @@ -0,0 +1,108 @@ +// This implements the std::map insert c++ example at: +// https://docs.microsoft.com/en-us/cpp/standard-library/map-class?view=msvc-160#example-19 +#define i_key int +#define i_val int +#define i_tag ii // Map of int => int +#include + +#define i_implement +#include +#define i_key int +#define i_val_str +#define i_tag istr // Map of int => cstr +#include + +#define i_key csmap_ii_raw +#define i_opt c_no_cmp +#define i_tag ii +#include + +void print_ii(csmap_ii map) { + c_foreach (e, csmap_ii, map) + printf("(%d, %d) ", e.ref->first, e.ref->second); + puts(""); +} + +void print_istr(csmap_istr map) { + c_foreach (e, csmap_istr, map) + printf("(%d, %s) ", e.ref->first, cstr_str(&e.ref->second)); + puts(""); +} + +int main(void) +{ + // insert single values + csmap_ii m1 = {0}; + csmap_ii_insert(&m1, 1, 10); + csmap_ii_push(&m1, c_LITERAL(csmap_ii_value){2, 20}); + + puts("The original key and mapped values of m1 are:"); + print_ii(m1); + + // intentionally attempt a duplicate, single element + csmap_ii_result ret = csmap_ii_insert(&m1, 1, 111); + if (!ret.inserted) { + csmap_ii_value pr = *ret.ref; + puts("Insert failed, element with key value 1 already exists."); + printf(" The existing element is (%d, %d)\n", pr.first, pr.second); + } + else { + puts("The modified key and mapped values of m1 are:"); + print_ii(m1); + } + puts(""); + + csmap_ii_insert(&m1, 3, 30); + puts("The modified key and mapped values of m1 are:"); + print_ii(m1); + puts(""); + + // The templatized version inserting a jumbled range + csmap_ii m2 = {0}; + cvec_ii v = {0}; + typedef cvec_ii_value ipair; + 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) + printf("(%d, %d) ", e.ref->first, e.ref->second); + puts(""); + + c_foreach (e, cvec_ii, v) + csmap_ii_insert_or_assign(&m2, e.ref->first, e.ref->second); + + puts("The modified key and mapped values of m2 are:"); + c_foreach (e, csmap_ii, m2) + printf("(%d, %d) ", e.ref->first, e.ref->second); + puts("\n"); + + // The templatized versions move-constructing elements + csmap_istr m3 = {0}; + csmap_istr_value ip1 = {475, cstr_lit("blue")}, ip2 = {510, cstr_lit("green")}; + + // single element + csmap_istr_insert(&m3, ip1.first, cstr_move(&ip1.second)); + puts("After the first move insertion, m3 contains:"); + print_istr(m3); + + // single element + csmap_istr_insert(&m3, ip2.first, cstr_move(&ip2.second)); + puts("After the second move insertion, m3 contains:"); + print_istr(m3); + puts(""); + + csmap_ii m4 = {0}; + // Insert the elements from an initializer_list + 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(""); + + cvec_ii_drop(&v); + csmap_istr_drop(&m3); + c_drop(csmap_ii, &m1, &m2, &m4); +} diff --git a/misc/examples/sortedmaps/csset_erase.c b/misc/examples/sortedmaps/csset_erase.c new file mode 100644 index 00000000..9c7f5e1a --- /dev/null +++ b/misc/examples/sortedmaps/csset_erase.c @@ -0,0 +1,41 @@ +#include + +#define i_key int +#include + +int main(void) +{ + 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); + puts(""); + + int val = 64; + csset_int_iter it; + printf("Show values >= %d:\n", val); + it = csset_int_lower_bound(&set, val); + + c_foreach (k, csset_int, it, csset_int_end(&set)) + printf(" %d", *k.ref); + puts(""); + + printf("Erase values >= %d:\n", val); + while (it.ref) + it = csset_int_erase_at(&set, it); + + c_foreach (k, csset_int, set) + printf(" %d", *k.ref); + puts(""); + + val = 40; + printf("Erase values < %d:\n", val); + it = csset_int_lower_bound(&set, val); + csset_int_erase_range(&set, csset_int_begin(&set), it); + + c_foreach (k, csset_int, set) + printf(" %d", *k.ref); + puts(""); + + csset_int_drop(&set); +} diff --git a/misc/examples/sortedmaps/gauss2.c b/misc/examples/sortedmaps/gauss2.c new file mode 100644 index 00000000..1ab8ade5 --- /dev/null +++ b/misc/examples/sortedmaps/gauss2.c @@ -0,0 +1,45 @@ +#include +#include + +#define i_implement +#include +#include + +// Declare int -> int sorted map. +#define i_key int +#define i_val int +#include + +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.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); + + // 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)); + csmap_int_insert(&hist, index, 0).ref->second += 1; + } + + // Print the gaussian bar chart + c_forpair (index, count, csmap_int, hist) { + int n = (int)round((double)*_.count * StdDev * Scale * 2.5 / (double)N); + if (n > 0) { + cstr_resize(&bar, n, '*'); + printf("%4d %s\n", *_.index, cstr_str(&bar)); + } + } + cstr_drop(&bar); + csmap_int_drop(&hist); +} diff --git a/misc/examples/sortedmaps/listmap.c b/misc/examples/sortedmaps/listmap.c new file mode 100644 index 00000000..04a605a7 --- /dev/null +++ b/misc/examples/sortedmaps/listmap.c @@ -0,0 +1,65 @@ +// This implements the multimap c++ example found at: +// https://en.cppreference.com/w/cpp/container/multimap/insert + +// Multimap entries +#define i_implement +#include +#define i_key_str +#include + +// Map of int => clist_str. +#define i_type Multimap +#define i_key int +#define i_valclass clist_str // set i_val = clist_str, bind clist_str_clone and clist_str_drop +#define i_cmp -c_default_cmp // like std::greater +#include + +void print(const char* lbl, const Multimap mmap) +{ + printf("%s ", lbl); + c_foreach (e, Multimap, mmap) { + c_foreach (s, clist_str, e.ref->second) + printf("{%d,%s} ", e.ref->first, cstr_str(s.ref)); + } + puts(""); +} + +void insert(Multimap* mmap, int key, const char* str) +{ + clist_str *list = &Multimap_insert(mmap, key, clist_str_init()).ref->second; + clist_str_emplace_back(list, str); +} + +int main(void) +{ + Multimap mmap = {0}; + + // list-initialize + typedef struct {int a; const char* b;} pair; + c_forlist (i, pair, {{2, "foo"}, {2, "bar"}, {3, "baz"}, {1, "abc"}, {5, "def"}}) + insert(&mmap, i.ref->a, i.ref->b); + print("#1", mmap); + + // insert using value_type + insert(&mmap, 5, "pqr"); + print("#2", mmap); + + // insert using make_pair + insert(&mmap, 6, "uvw"); + print("#3", mmap); + + insert(&mmap, 7, "xyz"); + print("#4", mmap); + + // insert using initialization_list + c_forlist (i, pair, {{5, "one"}, {5, "two"}}) + insert(&mmap, i.ref->a, i.ref->b); + print("#5", mmap); + + // FOLLOWING NOT IN ORIGINAL EXAMPLE: + // erase all entries with key 5 + Multimap_erase(&mmap, 5); + print("+5", mmap); + + Multimap_drop(&mmap); +} diff --git a/misc/examples/sortedmaps/mapmap.c b/misc/examples/sortedmaps/mapmap.c new file mode 100644 index 00000000..d3065659 --- /dev/null +++ b/misc/examples/sortedmaps/mapmap.c @@ -0,0 +1,64 @@ +// create a structure like: std::map>: +#define i_implement +#include + +// People: std::map +#define i_type People +#define i_key_str // name +#define i_val_str // email +#define i_keydrop(p) (printf("kdrop: %s\n", cstr_str(p)), cstr_drop(p)) // override +#include + +// Departments: std::map +#define i_type Departments +#define i_key_str // dep. name +#define i_valclass People +#include + + +void add(Departments* deps, const char* name, const char* email, const char* dep) +{ + People *people = &Departments_emplace(deps, dep, People_init()).ref->second; + People_emplace_or_assign(people, name, email); +} + +int contains(Departments* map, const char* name) +{ + int count = 0; + c_foreach (i, Departments, *map) + if (People_contains(&i.ref->second, name)) + ++count; + return count; +} + +int main(void) +{ + Departments map = {0}; + + add(&map, "Anna Kendro", "Anna@myplace.com", "Support"); + add(&map, "Terry Dane", "Terry@myplace.com", "Development"); + add(&map, "Kik Winston", "Kik@myplace.com", "Finance"); + add(&map, "Nancy Drew", "Nancy@live.com", "Development"); + add(&map, "Nick Denton", "Nick@myplace.com", "Finance"); + add(&map, "Stan Whiteword", "Stan@myplace.com", "Marketing"); + add(&map, "Serena Bath", "Serena@myplace.com", "Support"); + add(&map, "Patrick Dust", "Patrick@myplace.com", "Finance"); + add(&map, "Red Winger", "Red@gmail.com", "Marketing"); + add(&map, "Nick Denton", "Nick@yahoo.com", "Support"); + add(&map, "Colin Turth", "Colin@myplace.com", "Support"); + add(&map, "Dennis Kay", "Dennis@mail.com", "Marketing"); + add(&map, "Anne Dickens", "Anne@myplace.com", "Development"); + + c_foreach (i, Departments, map) + c_forpair (name, email, People, i.ref->second) + printf("%s: %s - %s\n", cstr_str(&i.ref->first), cstr_str(_.name), cstr_str(_.email)); + puts(""); + + printf("found Nick Denton: %d\n", contains(&map, "Nick Denton")); + printf("found Patrick Dust: %d\n", contains(&map, "Patrick Dust")); + printf("found Dennis Kay: %d\n", contains(&map, "Dennis Kay")); + printf("found Serena Bath: %d\n", contains(&map, "Serena Bath")); + puts("Done"); + + Departments_drop(&map); +} diff --git a/misc/examples/sortedmaps/multimap.c b/misc/examples/sortedmaps/multimap.c new file mode 100644 index 00000000..1068a5dc --- /dev/null +++ b/misc/examples/sortedmaps/multimap.c @@ -0,0 +1,102 @@ +#define i_implement +#include + +// Olympics multimap example + +struct OlympicsData { int year; const char *city, *country, *date; } ol_data[] = { + {2026, "Milan and Cortina d'Ampezzo", "Italy", "February 6-22"}, + {2022, "Beijing", "China", "February 4-20"}, + {2018, "PyeongChang", "South Korea", "February 9-25"}, + {2014, "Sochi", "Russia", "February 7-23"}, + {2010, "Vancouver", "Canada", "February 12-28"}, + {2006, "Torino", "Italy", "February 10-26"}, + {2002, "Salt Lake City", "United States", "February 8-24"}, + {1998, "Nagano", "Japan", "February 7-22"}, + {1994, "Lillehammer", "Norway", "February 12-27"}, + {1992, "Albertville", "France", "February 8-23"}, + {1988, "Calgary", "Canada", "February 13-28"}, + {1984, "Sarajevo", "Yugoslavia", "February 8-19"}, + {1980, "Lake Placid", "United States", "February 13-24"}, + {1976, "Innsbruck", "Austria", "February 4-15"}, + {1972, "Sapporo", "Japan", "February 3-13"}, + {1968, "Grenoble", "France", "February 6-18"}, + {1964, "Innsbruck", "Austria", "January 29-February 9"}, + {1960, "Squaw Valley", "United States", "February 18-28"}, + {1956, "Cortina d'Ampezzo", "Italy", "January 26 - February 5"}, + {1952, "Oslo", "Norway", "February 14 - 25"}, + {1948, "St. Moritz", "Switzerland", "January 30 - February 8"}, + {1944, "canceled", "canceled", "canceled"}, + {1940, "canceled", "canceled", "canceled"}, + {1936, "Garmisch-Partenkirchen", "Germany", "February 6 - 16"}, + {1932, "Lake Placid", "United States", "February 4 - 15"}, + {1928, "St. Moritz", "Switzerland", "February 11 - 19"}, + {1924, "Chamonix", "France", "January 25 - February 5"}, +}; + +typedef struct { int year; cstr city, date; } OlympicLoc; + +int OlympicLoc_cmp(const OlympicLoc* a, const OlympicLoc* b); +OlympicLoc OlympicLoc_clone(OlympicLoc loc); +void OlympicLoc_drop(OlympicLoc* self); + +// Create a clist, can be sorted by year. +#define i_keyclass OlympicLoc // binds _cmp, _clone and _drop. +#define i_tag OL +#include + +// Create a csmap where key is country name +#define i_key_str // binds cstr_equ, cstr_hash, cstr_clone, ++ +#define i_valclass clist_OL // binds clist_OL_clone, clist_OL_drop +#define i_tag OL +#include + +int OlympicLoc_cmp(const OlympicLoc* a, const OlympicLoc* b) { + return a->year - b->year; +} + +OlympicLoc OlympicLoc_clone(OlympicLoc loc) { + loc.city = cstr_clone(loc.city); + loc.date = cstr_clone(loc.date); + return loc; +} + +void OlympicLoc_drop(OlympicLoc* self) { + cstr_drop(&self->city); + cstr_drop(&self->date); +} + + +int main(void) +{ + // Define the multimap with destructor defered to when block is completed. + csmap_OL multimap = {0}; + const clist_OL empty = clist_OL_init(); + + for (size_t i = 0; i < c_arraylen(ol_data); ++i) + { + struct OlympicsData* d = &ol_data[i]; + OlympicLoc loc = {.year = d->year, + .city = cstr_from(d->city), + .date = cstr_from(d->date)}; + // Insert an empty list for each new country, and append the entry to the list. + // If country already exist in map, its list is returned from the insert function. + clist_OL* list = &csmap_OL_emplace(&multimap, d->country, empty).ref->second; + clist_OL_push_back(list, loc); + } + + // Sort locations by year for each country. + c_foreach (country, csmap_OL, multimap) + clist_OL_sort(&country.ref->second); + + // Print the multimap: + c_foreach (country, csmap_OL, multimap) + { + // Loop the locations for a country sorted by year + c_foreach (loc, clist_OL, country.ref->second) + printf("%s: %d, %s, %s\n", cstr_str(&country.ref->first), + loc.ref->year, + cstr_str(&loc.ref->city), + cstr_str(&loc.ref->date)); + } + csmap_OL_drop(&multimap); +} diff --git a/misc/examples/sortedmaps/new_smap.c b/misc/examples/sortedmaps/new_smap.c new file mode 100644 index 00000000..ee946c9a --- /dev/null +++ b/misc/examples/sortedmaps/new_smap.c @@ -0,0 +1,67 @@ +#define i_implement +#include +#include + +forward_csmap(PMap, struct Point, int); + +// Use forward declared PMap in struct +typedef struct { + PMap pntmap; + cstr name; +} MyStruct; + +// Point => int map +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_type PMap +#define i_key Point +#define i_val int +#define i_cmp point_cmp +#define i_is_forward +#include + +// cstr => cstr map +#define i_type SMap +#define i_key_str +#define i_val_str +#include + +// cstr set +#define i_type SSet +#define i_key_str +#include + + +int main(void) +{ + PMap pmap = c_init(PMap, { + {{42, 14}, 1}, + {{32, 94}, 2}, + {{62, 81}, 3}, + }); + SMap smap = c_init(SMap, { + {"Hello, friend", "this is the mapped value"}, + {"The brown fox", "jumped"}, + {"This is the time", "for all good things"}, + }); + SSet sset = {0}; + + c_forpair (p, i, PMap, pmap) + printf(" (%d,%d: %d)", _.p->x, _.p->y, *_.i); + puts(""); + + c_forpair (i, j, SMap, smap) + printf(" (%s: %s)\n", cstr_str(_.i), cstr_str(_.j)); + + SSet_emplace(&sset, "Hello, friend"); + SSet_emplace(&sset, "Goodbye, foe"); + printf("Found? %s\n", SSet_contains(&sset, "Hello, friend") ? "true" : "false"); + + PMap_drop(&pmap); + SMap_drop(&smap); + SSet_drop(&sset); +} diff --git a/misc/examples/sortedmaps/sorted_map.c b/misc/examples/sortedmaps/sorted_map.c new file mode 100644 index 00000000..89381554 --- /dev/null +++ b/misc/examples/sortedmaps/sorted_map.c @@ -0,0 +1,67 @@ +// https://iq.opengenus.org/containers-cpp-stl/ + +#include +#define i_key int +#define i_val int +#include + +int main(void) +{ + + // empty map containers + csmap_int gquiz1 = {0}, gquiz2 = {0}; + c_defer( + csmap_int_drop(&gquiz1), + csmap_int_drop(&gquiz2) + ){ + // insert elements in random order + csmap_int_insert(&gquiz1, 2, 30); + csmap_int_insert(&gquiz1, 4, 20); + csmap_int_insert(&gquiz1, 7, 10); + csmap_int_insert(&gquiz1, 5, 50); + csmap_int_insert(&gquiz1, 3, 60); + csmap_int_insert(&gquiz1, 1, 40); + csmap_int_insert(&gquiz1, 6, 50); + + // printing map gquiz1 + printf("\nThe map gquiz1 is :\n\tKEY\tELEMENT\n"); + c_foreach (itr, csmap_int, gquiz1) + printf("\t%d\t%d\n", itr.ref->first, itr.ref->second); + printf("\n"); + + // assigning the elements from gquiz1 to gquiz2 + c_foreach (i, csmap_int, gquiz1) + csmap_int_insert(&gquiz2, i.ref->first, i.ref->second); + + // print all elements of the map gquiz2 + printf("\nThe map gquiz2 is :\n\tKEY\tELEMENT\n"); + c_foreach (itr, csmap_int, gquiz2) + printf("\t%d\t%d\n", itr.ref->first, itr.ref->second); + printf("\n"); + + // remove all elements up to element with key=3 in gquiz2 + printf("\ngquiz2 after removal of elements less than key=3 :\n"); + printf("\tKEY\tELEMENT\n"); + csmap_int_erase_range(&gquiz2, csmap_int_begin(&gquiz2), + csmap_int_find(&gquiz2, 3)); + c_foreach (itr, csmap_int, gquiz2) + printf("\t%d\t%d\n", itr.ref->first, itr.ref->second); + printf("\n"); + + // remove all elements with key = 4 + int num = csmap_int_erase(&gquiz2, 4); + printf("\ngquiz2.erase(4) : %d removed\n", num); + printf("\tKEY\tELEMENT\n"); + c_foreach (itr, csmap_int, gquiz2) + printf("\t%d\t%d\n", itr.ref->first, itr.ref->second); + printf("\n"); + + // lower bound and upper bound for map gquiz1 key = 5 + printf("gquiz1.lower_bound(5) : "); + printf("\tKEY = %d\t", csmap_int_lower_bound(&gquiz1, 5).ref->first); + printf("\tELEMENT = %d\n", csmap_int_lower_bound(&gquiz1, 5).ref->second); + printf("gquiz1.upper_bound(5) : "); + printf("\tKEY = %d\t", csmap_int_lower_bound(&gquiz1, 5+1).ref->first); + printf("\tELEMENT = %d\n", csmap_int_lower_bound(&gquiz1, 5+1).ref->second); + } +} diff --git a/misc/examples/spans/multidim.c b/misc/examples/spans/multidim.c new file mode 100644 index 00000000..798a1126 --- /dev/null +++ b/misc/examples/spans/multidim.c @@ -0,0 +1,67 @@ +// Example based on https://en.cppreference.com/w/cpp/container/mdspan +#define i_val int +#include +#include +#include + +using_cspan3(ispan, int); + +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}); + + // 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; + 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/spans/printspan.c b/misc/examples/spans/printspan.c new file mode 100644 index 00000000..cd3c5f4f --- /dev/null +++ b/misc/examples/spans/printspan.c @@ -0,0 +1,52 @@ +// printspan.c + +#include +#define i_implement +#include +#define i_key int +#include +#define i_key int +#include +#define i_key_str +#include + +#include +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(void) +{ + intspan sp1 = cspan_init(intspan, {1, 2}); + printMe( sp1 ); + + printMe( c_init(intspan, {1, 2, 3}) ); + + int arr[] = {1, 2, 3, 4, 5, 6}; + intspan sp2 = cspan_from_array(arr); + printMe( c_LITERAL(intspan)cspan_subspan(&sp2, 1, 4) ); + + cvec_int vec = c_init(cvec_int, {1, 2, 3, 4, 5}); + printMe( c_LITERAL(intspan)cspan_from(&vec) ); + + printMe( sp2 ); + + cstack_int stk = c_init(cstack_int, {1, 2, 3, 4, 5, 6, 7}); + printMe( c_LITERAL(intspan)cspan_from(&stk) ); + + csset_str set = c_init(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); + csset_str_drop(&set); +} diff --git a/misc/examples/splitstr.c b/misc/examples/splitstr.c deleted file mode 100644 index ef7ed174..00000000 --- a/misc/examples/splitstr.c +++ /dev/null @@ -1,21 +0,0 @@ -#include -#define i_import // cstr + utf8 functions -#include -#define i_implement -#include - -int main(void) -{ - puts("Split with c_fortoken (csview):"); - - c_fortoken (i, "Hello World C99!", " ") - printf("'%.*s'\n", c_SV(i.token)); - - puts("\nSplit with c_formatch (regex):"); - - cregex re = cregex_from("[^ ]+"); - c_formatch (i, &re, " Hello World C99! ") - printf("'%.*s'\n", c_SV(i.match[0])); - - cregex_drop(&re); -} diff --git a/misc/examples/sso_map.c b/misc/examples/sso_map.c deleted file mode 100644 index 4f84b651..00000000 --- a/misc/examples/sso_map.c +++ /dev/null @@ -1,19 +0,0 @@ -#define i_implement -#include -#define i_key_str -#define i_val_str -#include - -int main(void) -{ - cmap_str m = {0}; - cmap_str_emplace(&m, "Test short", "This is a short string"); - cmap_str_emplace(&m, "Test long ", "This is a longer string"); - - c_forpair (k, v, cmap_str, m) - printf("%s: '%s' Len=%" c_ZI ", Is long: %s\n", - cstr_str(_.k), cstr_str(_.v), cstr_size(_.v), - cstr_is_long(_.v) ? "true" : "false"); - - cmap_str_drop(&m); -} diff --git a/misc/examples/sso_substr.c b/misc/examples/sso_substr.c deleted file mode 100644 index 687658df..00000000 --- a/misc/examples/sso_substr.c +++ /dev/null @@ -1,21 +0,0 @@ -#define i_implement -#include -#define i_implement -#include - -int main(void) -{ - cstr str = cstr_lit("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" - 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" - 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/stack.c b/misc/examples/stack.c deleted file mode 100644 index 6297fb6f..00000000 --- a/misc/examples/stack.c +++ /dev/null @@ -1,32 +0,0 @@ - -#include - -#define i_tag i -#define i_capacity 100 -#define i_key int -#include - -#define i_tag c -#define i_key char -#include - -int main(void) { - cstack_i stack = {0}; - cstack_c chars = {0}; - - c_forrange (i, 101) - cstack_i_push(&stack, (int)(i*i)); - - printf("%d\n", *cstack_i_top(&stack)); - - c_forrange (i, 90) - cstack_i_pop(&stack); - - c_foreach (i, cstack_i, stack) - printf(" %d", *i.ref); - puts(""); - printf("top: %d\n", *cstack_i_top(&stack)); - - cstack_i_drop(&stack); - cstack_c_drop(&chars); -} diff --git a/misc/examples/strings/cstr_match.c b/misc/examples/strings/cstr_match.c new file mode 100644 index 00000000..be03e981 --- /dev/null +++ b/misc/examples/strings/cstr_match.c @@ -0,0 +1,26 @@ +#define i_implement +#include +#include +#include + +int main(void) +{ + cstr ss = cstr_lit("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 ? "" : cstr_str(&ss) + pos); + printf("equals: %d\n", cstr_equals(&ss, "The quick brown fox jumps over the lazy dog.JPG")); + printf("contains: %d\n", cstr_contains(&ss, "umps ove")); + printf("starts_with: %d\n", cstr_starts_with(&ss, "The quick brown")); + printf("ends_with: %d\n", cstr_ends_with(&ss, ".jpg")); + printf("ends_with: %d\n", cstr_ends_with(&ss, ".JPG")); + + cstr s1 = cstr_lit("hell😀 w😀rl🐨"); + csview ch1 = cstr_u8_chr(&s1, 7); + csview ch2 = cstr_u8_chr(&s1, 10); + printf("%s\nsize: %" c_ZI ", %" c_ZI "\n", cstr_str(&s1), cstr_u8_size(&s1), cstr_size(&s1)); + printf("ch1: %.*s\n", c_SV(ch1)); + printf("ch2: %.*s\n", c_SV(ch2)); + + c_drop(cstr, &ss, &s1); +} diff --git a/misc/examples/strings/replace.c b/misc/examples/strings/replace.c new file mode 100644 index 00000000..59a56bf7 --- /dev/null +++ b/misc/examples/strings/replace.c @@ -0,0 +1,36 @@ +#define i_implement +#include + +int main(void) +{ + const char *base = "this is a test string."; + const char *s2 = "n example"; + const char *s3 = "sample phrase"; + + // replace signatures used in the same order as described above: + + // Ustring positions: 0123456789*123456789*12345 + cstr s = cstr_from(base); // "this is a test string." + cstr m = cstr_clone(s); + + cstr_append(&m, cstr_str(&m)); + cstr_append(&m, cstr_str(&m)); + printf("%s\n", cstr_str(&m)); + + cstr_replace_at(&s, 9, 5, s2); // "this is an example string." (1) + printf("(1) %s\n", cstr_str(&s)); + + cstr_replace_at_sv(&s, 19, 6, c_sv(s3+7, 6)); // "this is an example phrase." (2) + printf("(2) %s\n", cstr_str(&s)); + + cstr_replace_at(&s, 8, 10, "just a"); // "this is just a phrase." (3) + printf("(3) %s\n", cstr_str(&s)); + + cstr_replace_at_sv(&s, 8, 6, c_sv("a shorty", 7)); // "this is a short phrase." (4) + printf("(4) %s\n", cstr_str(&s)); + + cstr_replace_at(&s, 22, 1, "!!!"); // "this is a short phrase!!!" (5) + printf("(5) %s\n", cstr_str(&s)); + + c_drop(cstr, &s, &m); +} diff --git a/misc/examples/strings/splitstr.c b/misc/examples/strings/splitstr.c new file mode 100644 index 00000000..ef7ed174 --- /dev/null +++ b/misc/examples/strings/splitstr.c @@ -0,0 +1,21 @@ +#include +#define i_import // cstr + utf8 functions +#include +#define i_implement +#include + +int main(void) +{ + puts("Split with c_fortoken (csview):"); + + c_fortoken (i, "Hello World C99!", " ") + printf("'%.*s'\n", c_SV(i.token)); + + puts("\nSplit with c_formatch (regex):"); + + cregex re = cregex_from("[^ ]+"); + c_formatch (i, &re, " Hello World C99! ") + printf("'%.*s'\n", c_SV(i.match[0])); + + cregex_drop(&re); +} diff --git a/misc/examples/strings/sso_map.c b/misc/examples/strings/sso_map.c new file mode 100644 index 00000000..4f84b651 --- /dev/null +++ b/misc/examples/strings/sso_map.c @@ -0,0 +1,19 @@ +#define i_implement +#include +#define i_key_str +#define i_val_str +#include + +int main(void) +{ + cmap_str m = {0}; + cmap_str_emplace(&m, "Test short", "This is a short string"); + cmap_str_emplace(&m, "Test long ", "This is a longer string"); + + c_forpair (k, v, cmap_str, m) + printf("%s: '%s' Len=%" c_ZI ", Is long: %s\n", + cstr_str(_.k), cstr_str(_.v), cstr_size(_.v), + cstr_is_long(_.v) ? "true" : "false"); + + cmap_str_drop(&m); +} diff --git a/misc/examples/strings/sso_substr.c b/misc/examples/strings/sso_substr.c new file mode 100644 index 00000000..687658df --- /dev/null +++ b/misc/examples/strings/sso_substr.c @@ -0,0 +1,21 @@ +#define i_implement +#include +#define i_implement +#include + +int main(void) +{ + cstr str = cstr_lit("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" + 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" + 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/strings/sview_split.c b/misc/examples/strings/sview_split.c new file mode 100644 index 00000000..ac275da0 --- /dev/null +++ b/misc/examples/strings/sview_split.c @@ -0,0 +1,20 @@ +#define i_implement +#include +#define i_implement +#include + +int main(void) +{ + // No memory allocations or string length calculations! + const csview date = c_sv("2021/03/12"); + intptr_t pos = 0; + const csview year = csview_token(date, "/", &pos); + const csview month = csview_token(date, "/", &pos); + const csview day = csview_token(date, "/", &pos); + + printf("%.*s, %.*s, %.*s\n", c_SV(year), c_SV(month), c_SV(day)); + + cstr y = cstr_from_sv(year), m = cstr_from_sv(month), d = cstr_from_sv(day); + printf("%s, %s, %s\n", cstr_str(&y), cstr_str(&m), cstr_str(&d)); + c_drop(cstr, &y, &m, &d); +} diff --git a/misc/examples/strings/utf8replace_c.c b/misc/examples/strings/utf8replace_c.c new file mode 100644 index 00000000..1d54486f --- /dev/null +++ b/misc/examples/strings/utf8replace_c.c @@ -0,0 +1,25 @@ +#define i_implement +#include + +int main(void) +{ + cstr hello = cstr_lit("hell😀 w😀rld"); + printf("%s\n", cstr_str(&hello)); + + /* replace second smiley at utf8 codepoint pos 7 */ + cstr_u8_replace_at(&hello, + cstr_u8_to_pos(&hello, 7), + 1, + c_sv("🐨") + ); + printf("%s\n", cstr_str(&hello)); + + c_foreach (c, cstr, hello) + printf("%.*s,", c_SV(c.u8.chr)); + + cstr str = cstr_lit("scooby, dooby doo"); + cstr_replace(&str, "oo", "00"); + printf("\n%s\n", cstr_str(&str)); + + c_drop(cstr, &hello, &str); +} diff --git a/misc/examples/strings/utf8replace_rs.rs b/misc/examples/strings/utf8replace_rs.rs new file mode 100644 index 00000000..8b163b4e --- /dev/null +++ b/misc/examples/strings/utf8replace_rs.rs @@ -0,0 +1,22 @@ +pub fn main() { + let mut hello = String::from("hell😀 w😀rld"); + println!("{}", hello); + + /* replace second smiley at utf8 codepoint pos 7 */ + hello.replace_range( + hello + .char_indices() + .nth(7) + .map(|(pos, ch)| (pos..pos + ch.len_utf8())) + .unwrap(), + "🐨", + ); + println!("{}", hello); + + for c in hello.chars() { + print!("{},", c); + } + + let str = "If you find the time, you will find the winner"; + println!("\n{}", str.replace("find", "match")); +} diff --git a/misc/examples/sview_split.c b/misc/examples/sview_split.c deleted file mode 100644 index ac275da0..00000000 --- a/misc/examples/sview_split.c +++ /dev/null @@ -1,20 +0,0 @@ -#define i_implement -#include -#define i_implement -#include - -int main(void) -{ - // No memory allocations or string length calculations! - const csview date = c_sv("2021/03/12"); - intptr_t pos = 0; - const csview year = csview_token(date, "/", &pos); - const csview month = csview_token(date, "/", &pos); - const csview day = csview_token(date, "/", &pos); - - printf("%.*s, %.*s, %.*s\n", c_SV(year), c_SV(month), c_SV(day)); - - cstr y = cstr_from_sv(year), m = cstr_from_sv(month), d = cstr_from_sv(day); - printf("%s, %s, %s\n", cstr_str(&y), cstr_str(&m), cstr_str(&d)); - c_drop(cstr, &y, &m, &d); -} diff --git a/misc/examples/triples.c b/misc/examples/triples.c deleted file mode 100644 index 9f2fcc1e..00000000 --- a/misc/examples/triples.c +++ /dev/null @@ -1,72 +0,0 @@ -// https://quuxplusone.github.io/blog/2019/03/06/pythagorean-triples/ - -#include -#include - -int gcd(int a, int b) { - while (b) { - int t = a % b; - a = b; - b = t; - } - return a; -} - -void triples_vanilla(int n) { - for (int c = 5, i = 0; 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 && gcd(a, b) == 1) { - printf("%d: {%d, %d, %d}\n", ++i, a, b, c); - if (--n == 0) goto done; - } - } - } - } - done:; -} - -struct triples { - int size, count; - int a, b, c; - int cco_state; -}; - -int triples_coro(struct triples* t) { - cco_routine(t) { - t->count = 0; - for (t->c = 5; t->size; ++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->count++ == t->size) - cco_return; - cco_yield(); - } - } - } - } - cco_cleanup: - puts("done"); - } - return 0; -} - -int main(void) -{ - puts("Vanilla triples:"); - triples_vanilla(5); - - puts("\nCoroutine triples:"); - struct triples t = {.size=INT32_MAX}; - int n = 0; - - while (triples_coro(&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/unordered_set.c b/misc/examples/unordered_set.c deleted file mode 100644 index dd899d78..00000000 --- a/misc/examples/unordered_set.c +++ /dev/null @@ -1,45 +0,0 @@ -// https://iq.opengenus.org/containers-cpp-stl/ -// C program to demonstrate various function of stc cset -#define i_implement -#include -#define i_key_str -#include - -int main(void) -{ - // declaring set for storing string data-type - cset_str stringSet = {0}; - c_defer( - cset_str_drop(&stringSet) - ){ - // inserting various string, same string will be stored - // once in set - cset_str_emplace(&stringSet, "code"); - cset_str_emplace(&stringSet, "in"); - cset_str_emplace(&stringSet, "C"); - cset_str_emplace(&stringSet, "is"); - cset_str_emplace(&stringSet, "fast"); - - const char* key = "slow"; - - // find returns end iterator if key is not found, - // else it returns iterator to that key - - if (cset_str_find(&stringSet, key).ref == NULL) - printf("\"%s\" not found\n", key); - else - printf("Found \"%s\"\n", key); - - key = "C"; - if (!cset_str_contains(&stringSet, key)) - printf("\"%s\" not found\n", key); - else - printf("Found \"%s\"\n", key); - - // now iterating over whole set and printing its - // content - printf("All elements :\n"); - c_foreach (itr, cset_str, stringSet) - printf("%s\n", cstr_str(itr.ref)); - } -} diff --git a/misc/examples/utf8replace_c.c b/misc/examples/utf8replace_c.c deleted file mode 100644 index 1d54486f..00000000 --- a/misc/examples/utf8replace_c.c +++ /dev/null @@ -1,25 +0,0 @@ -#define i_implement -#include - -int main(void) -{ - cstr hello = cstr_lit("hell😀 w😀rld"); - printf("%s\n", cstr_str(&hello)); - - /* replace second smiley at utf8 codepoint pos 7 */ - cstr_u8_replace_at(&hello, - cstr_u8_to_pos(&hello, 7), - 1, - c_sv("🐨") - ); - printf("%s\n", cstr_str(&hello)); - - c_foreach (c, cstr, hello) - printf("%.*s,", c_SV(c.u8.chr)); - - cstr str = cstr_lit("scooby, dooby doo"); - cstr_replace(&str, "oo", "00"); - printf("\n%s\n", cstr_str(&str)); - - c_drop(cstr, &hello, &str); -} diff --git a/misc/examples/utf8replace_rs.rs b/misc/examples/utf8replace_rs.rs deleted file mode 100644 index 8b163b4e..00000000 --- a/misc/examples/utf8replace_rs.rs +++ /dev/null @@ -1,22 +0,0 @@ -pub fn main() { - let mut hello = String::from("hell😀 w😀rld"); - println!("{}", hello); - - /* replace second smiley at utf8 codepoint pos 7 */ - hello.replace_range( - hello - .char_indices() - .nth(7) - .map(|(pos, ch)| (pos..pos + ch.len_utf8())) - .unwrap(), - "🐨", - ); - println!("{}", hello); - - for c in hello.chars() { - print!("{},", c); - } - - let str = "If you find the time, you will find the winner"; - println!("\n{}", str.replace("find", "match")); -} diff --git a/misc/examples/vectors/lower_bound.c b/misc/examples/vectors/lower_bound.c new file mode 100644 index 00000000..bea828f2 --- /dev/null +++ b/misc/examples/vectors/lower_bound.c @@ -0,0 +1,66 @@ +#include + +#define i_key int +#define i_cmp_native +#include + +#define i_key int +#include + +int main(void) +{ + // TEST SORTED VECTOR + { + int key, *res; + cvec_int vec = c_init(cvec_int, {40, 600, 1, 7000, 2, 500, 30}); + + cvec_int_sort(&vec); + + key = 100; + res = cvec_int_lower_bound(&vec, key).ref; + if (res) + printf("Sorted Vec %d: lower bound: %d\n", key, *res); // 500 + + key = 10; + cvec_int_iter it1 = cvec_int_lower_bound(&vec, key); + if (it1.ref) + printf("Sorted Vec %3d: lower_bound: %d\n", key, *it1.ref); // 30 + + key = 600; + cvec_int_iter it2 = cvec_int_binary_search(&vec, key); + if (it2.ref) + printf("Sorted Vec %d: bin. search: %d\n", key, *it2.ref); // 600 + + c_foreach (i, cvec_int, it1, it2) + printf(" %d\n", *i.ref); + + puts(""); + cvec_int_drop(&vec); + } + + // TEST SORTED SET + { + int key, *res; + csset_int set = c_init(csset_int, {40, 600, 1, 7000, 2, 500, 30}); + + key = 100; + res = csset_int_lower_bound(&set, key).ref; + if (res) + printf("Sorted Set %d: lower bound: %d\n", key, *res); // 500 + + key = 10; + csset_int_iter it1 = csset_int_lower_bound(&set, key); + if (it1.ref) + printf("Sorted Set %3d: lower bound: %d\n", key, *it1.ref); // 30 + + key = 600; + csset_int_iter it2 = csset_int_find(&set, key); + if (it2.ref) + printf("Sorted Set %d: find : %d\n", key, *it2.ref); // 600 + + c_foreach (i, csset_int, it1, it2) + printf(" %d\n", *i.ref); + + csset_int_drop(&set); + } +} diff --git a/misc/examples/vectors/new_vec.c b/misc/examples/vectors/new_vec.c new file mode 100644 index 00000000..88efd55a --- /dev/null +++ b/misc/examples/vectors/new_vec.c @@ -0,0 +1,43 @@ +#include +#include + +forward_cvec(cvec_i32, int); +forward_cvec(cvec_pnt, struct Point); + +typedef struct MyStruct { + cvec_i32 intvec; + cvec_pnt pntvec; +} MyStruct; + +#define i_key int +#define i_tag i32 +#define i_is_forward +#include + +typedef struct Point { int x, y; } 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 +#include + +int main(void) +{ + MyStruct my = {0}; + + 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); + + c_foreach (i, cvec_pnt, my.pntvec) + printf(" (%d %d)", i.ref->x, i.ref->y); + puts(""); + + cvec_i32_drop(&my.intvec); + cvec_pnt_drop(&my.pntvec); +} diff --git a/misc/examples/vectors/stack.c b/misc/examples/vectors/stack.c new file mode 100644 index 00000000..6297fb6f --- /dev/null +++ b/misc/examples/vectors/stack.c @@ -0,0 +1,32 @@ + +#include + +#define i_tag i +#define i_capacity 100 +#define i_key int +#include + +#define i_tag c +#define i_key char +#include + +int main(void) { + cstack_i stack = {0}; + cstack_c chars = {0}; + + c_forrange (i, 101) + cstack_i_push(&stack, (int)(i*i)); + + printf("%d\n", *cstack_i_top(&stack)); + + c_forrange (i, 90) + cstack_i_pop(&stack); + + c_foreach (i, cstack_i, stack) + printf(" %d", *i.ref); + puts(""); + printf("top: %d\n", *cstack_i_top(&stack)); + + cstack_i_drop(&stack); + cstack_c_drop(&chars); +} diff --git a/misc/examples/vikings.c b/misc/examples/vikings.c deleted file mode 100644 index d6125854..00000000 --- a/misc/examples/vikings.c +++ /dev/null @@ -1,59 +0,0 @@ -#define i_implement -#include - -typedef struct Viking { - cstr name; - cstr country; -} Viking; - -void Viking_drop(Viking* vk) { - cstr_drop(&vk->name); - cstr_drop(&vk->country); -} - -// Define Viking lookup struct with hash, cmp, and convertion functions between Viking and RViking structs: - -typedef struct RViking { - const char* name; - const char* country; -} RViking; - -static inline int RViking_cmp(const RViking* rx, const RViking* ry) { - int c = strcmp(rx->name, ry->name); - return c ? c : strcmp(rx->country, ry->country); -} - -static inline Viking Viking_from(RViking raw) { // note: parameter is by value - return c_LITERAL(Viking){cstr_from(raw.name), cstr_from(raw.country)}; -} - -static inline RViking Viking_toraw(const Viking* vp) { - return c_LITERAL(RViking){cstr_str(&vp->name), cstr_str(&vp->country)}; -} - -// With this in place, we define the Viking => int hash map type: -#define i_type Vikings -#define i_keyclass Viking // key type -#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_val int // mapped type -#include - -int main(void) -{ - Vikings vikings = {0}; - 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, c_LITERAL(RViking){"Einar", "Norway"}); - v->second += 3; // add 3 hp points to Einar - - c_forpair (vk, hp, Vikings, vikings) { - printf("%s of %s has %d hp\n", cstr_str(&_.vk->name), cstr_str(&_.vk->country), *_.hp); - } - Vikings_drop(&vikings); -} -- cgit v1.2.3