From 4578ae03cea28def01dc9f5fe882234857b1238e Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Tue, 18 May 2021 22:08:47 +0200 Subject: Added the new c_defer(), c_with(), c_withvar() macros into the examples. --- docs/ccommon_api.md | 26 +++++----- examples/advanced.c | 34 +++++++------- examples/birthday.c | 26 +++++----- examples/bits.c | 114 ++++++++++++++++++++++---------------------- examples/cpque.c | 40 ++++++++-------- examples/demos.c | 125 +++++++++++++++++++++++++------------------------ examples/ex_gauss1.c | 48 +++++++++---------- examples/ex_gauss2.c | 29 ++++++------ examples/inits.c | 110 ++++++++++++++++++++++--------------------- examples/list.c | 77 +++++++++++++++--------------- examples/list_erase.c | 30 ++++++------ examples/list_splice.c | 34 +++++++------- examples/mapmap.c | 27 +++++------ examples/olympics.c | 33 +++++++------ examples/phonebook.c | 53 +++++++++++---------- examples/prime.c | 17 ++++--- examples/priority.c | 35 +++++++------- examples/queue.c | 30 ++++++------ examples/replace.c | 49 ++++++++++--------- examples/stack.c | 24 +++++----- examples/stc_astar.c | 78 +++++++++++++++--------------- examples/svmap.c | 40 ++++++++-------- examples/words.c | 37 ++++++++------- stc/carray.h | 31 ++++++------ stc/cbits.h | 39 +++++++-------- stc/ccommon.h | 9 ++-- stc/clist.h | 31 ++++++------ stc/cmap.h | 27 ++++++----- stc/cpque.h | 20 ++++---- stc/cqueue.h | 28 +++++------ stc/csmap.h | 23 ++++----- stc/cstack.h | 15 +++--- stc/cstr.h | 2 +- 33 files changed, 679 insertions(+), 662 deletions(-) diff --git a/docs/ccommon_api.md b/docs/ccommon_api.md index eb7918b9..75e27327 100644 --- a/docs/ccommon_api.md +++ b/docs/ccommon_api.md @@ -5,7 +5,7 @@ The following handy macros are safe to use, i.e. have no side-effects. ### c_var, c_emplace **c_var** declares and initializes any container with an array of elements. **c_emplace** adds elements to any existing container: ```c -c_var(cvec_i, vec, {1, 2, 3}); // declare and emplace +c_var (cvec_i, vec, {1, 2, 3}); // declare and emplace c_emplace(cvec_i, vec, {4, 5, 6}); // adds to existing vec ``` @@ -49,17 +49,19 @@ c_foreach (i, csset_x, it, csset_x_end(&set)) printf(" %d", *i.ref); // 7 12 23 ``` -### c_with, c_withbuffer, c_breakwith -General defer in block mechanics. **c_withbuffer** is special for buffers, uses stack memory if buf is up to 256 bytes, -and heap memory otherwise. +### c_defer, c_with, c_withvar, c_withbuf, c_breakwith +General defer mechanics. These macros allows to specify destructors explicitly or implicitly where the +constructors are defined. This ensures that resources are released after usage, and avoids memory leaks. -***NB***: Use only **c_breakwith** to break out of the block if needed, never use **return**, **break**, -or **goto** inside a with-block. +**NB**: ***Only*** use `c_breakwith` to break out of the `c_with`-block if needed. ***Never*** use `return`, +`break`, or `goto` inside the block. -| Usage | Description | -|:-------------------------------|:-------------------------------------| -| `c_with (acquire, release)` | Do `acquire`. Defer `release` to end | -| `c_withbuffer (buf, type, n)` | Declare, allocate and free buf | +| Usage | Description | +|:-------------------------------|:-------------------------------------------------| +| `c_with (acquire, release)` | Do `acquire`. Defer `release` to end of block | +| `c_defer (release)` | Defer `release` to end of defer block | +| `c_withvar (ctype, v)` | `c_with (ctype v = ctype_init(), ctype_del(&v))` | +| `c_withbuf (buf, type, n)` | Declare, allocate and free memory buffer | The `acquire`argument must be of the form: `type var = get_resource`. @@ -76,11 +78,11 @@ cvec_str readFile(const char* name) // receiver should check errno variable cvec_str vec = cvec_str_init(); - c_with (FILE* fp = fopen(name, "r"), fclose(fp)) + c_with (FILE* fp = fopen(name, "r"), fclose(fp)) { c_with (cstr line = cstr_null, cstr_del(&line)) while (cstr_getline(&line, fp)) cvec_str_emplace_back(&vec, line.str); - + } return vec; } diff --git a/examples/advanced.c b/examples/advanced.c index b2dd1e57..6d5486ae 100644 --- a/examples/advanced.c +++ b/examples/advanced.c @@ -41,22 +41,22 @@ using_cmap_keydef(vk, Viking, int, vikingraw_equals, vikingraw_hash, int main() { - cmap_vk vikings = cmap_vk_init(); - c_emplace(cmap_vk, vikings, { - { {"Einar", "Norway"}, 20}, - { {"Olaf", "Denmark"}, 24}, - { {"Harald", "Iceland"}, 12}, - }); - VikingRaw bjorn = {"Bjorn", "Sweden"}; - cmap_vk_emplace_or_assign(&vikings, bjorn, 10); - - VikingRaw einar = {"Einar", "Norway"}; - cmap_vk_value_t *e = cmap_vk_find(&vikings, einar).ref; - e->second += 3; // add 3 hp points to Einar - cmap_vk_emplace(&vikings, einar, 0).ref->second += 5; // add 5 more to Einar - - c_foreach (k, cmap_vk, vikings) { - printf("%s of %s has %d hp\n", k.ref->first.name.str, k.ref->first.country.str, k.ref->second); + c_with (cmap_vk vikings = cmap_vk_init(), cmap_vk_del(&vikings)) { + c_emplace(cmap_vk, vikings, { + { {"Einar", "Norway"}, 20}, + { {"Olaf", "Denmark"}, 24}, + { {"Harald", "Iceland"}, 12}, + }); + VikingRaw bjorn = {"Bjorn", "Sweden"}; + cmap_vk_emplace_or_assign(&vikings, bjorn, 10); + + VikingRaw einar = {"Einar", "Norway"}; + cmap_vk_value_t *e = cmap_vk_find(&vikings, einar).ref; + e->second += 3; // add 3 hp points to Einar + cmap_vk_emplace(&vikings, einar, 0).ref->second += 5; // add 5 more to Einar + + c_foreach (k, cmap_vk, vikings) { + printf("%s of %s has %d hp\n", k.ref->first.name.str, k.ref->first.country.str, k.ref->second); + } } - cmap_vk_del(&vikings); } \ No newline at end of file diff --git a/examples/birthday.c b/examples/birthday.c index b2fc834c..18e9cd77 100644 --- a/examples/birthday.c +++ b/examples/birthday.c @@ -34,19 +34,21 @@ void test_distribution(void) printf("distribution test: 2^%d values\n", BITS); stc64_t rng = stc64_init(seed); const size_t N = 1ull << BITS ; - cmap_x map = cmap_x_init(); - - c_forrange (N) { - uint64_t k = stc64_rand(&rng); - cmap_x_emplace(&map, k & 0xf, 0).ref->second += 1; + + c_with (cmap_x map = cmap_x_init(), cmap_x_del(&map)) { + c_forrange (N) { + uint64_t k = stc64_rand(&rng); + cmap_x_emplace(&map, k & 0xf, 0).ref->second += 1; + } + + uint64_t sum = 0; + c_foreach (i, cmap_x, map) sum += i.ref->second; + sum /= map.size; + + c_foreach (i, cmap_x, map) { + printf("%4u: %zu - %zu: %11.8f\n", i.ref->first, i.ref->second, sum, (1 - (double) i.ref->second / sum)); + } } - - uint64_t sum = 0; - c_foreach (i, cmap_x, map) sum += i.ref->second; - sum /= map.size; - - c_foreach (i, cmap_x, map) - printf("%4u: %zu - %zu: %11.8f\n", i.ref->first, i.ref->second, sum, (1 - (double) i.ref->second / sum)); } int main() diff --git a/examples/bits.c b/examples/bits.c index e7b843fb..65be30ac 100644 --- a/examples/bits.c +++ b/examples/bits.c @@ -1,61 +1,61 @@ #include #include -int main() { - cbits set = cbits_with_size(23, true); - printf("count %zu, %zu\n", cbits_count(set), set.size); - cbits s1 = cbits_from_str("1110100110111"); - char buf[256]; - cbits_to_str(s1, buf, 0, -1); - printf("buf: %s: %zu\n", buf, cbits_count(s1)); - - cbits_reset(&set, 9); - cbits_resize(&set, 43, false); - c_withbuffer (str, char, set.size + 1) - printf(" str: %s\n", cbits_to_str(set, str, 0, -1)); - - printf("%4zu: ", set.size); - c_forrange (i, int, set.size) - 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("%4zu: ", set.size); - c_forrange (i, int, set.size) - printf("%d", cbits_test(set, i)); - - puts("\nIterate:"); - printf("%4zu: ", set.size); - c_forrange (i, int, set.size) - printf("%d", cbits_test(set, i)); - puts(""); - - cbits 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, int, s2.size) - printf("%d", cbits_test(s2, i)); - puts(""); - - printf(" xor: "); - cbits_xor(&set, s2); - c_forrange (i, int, set.size) - printf("%d", cbits_test(set, i)); - puts(""); - - cbits_set_all(&set, false); - printf("%4zu: ", set.size); - c_forrange (i, int, set.size) - printf("%d", cbits_test(set, i)); - puts(""); - - cbits_del(&s2); - cbits_del(&set); +int main() +{ + c_with (cbits set = cbits_with_size(23, true), cbits_del(&set)) { + printf("count %zu, %zu\n", cbits_count(set), set.size); + cbits s1 = cbits_from_str("1110100110111"); + char buf[256]; + cbits_to_str(s1, buf, 0, -1); + printf("buf: %s: %zu\n", buf, cbits_count(s1)); + + cbits_reset(&set, 9); + cbits_resize(&set, 43, false); + c_withbuf (str, char, set.size + 1) + printf(" str: %s\n", cbits_to_str(set, str, 0, -1)); + + printf("%4zu: ", set.size); + c_forrange (i, int, set.size) + 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("%4zu: ", set.size); + c_forrange (i, int, set.size) + printf("%d", cbits_test(set, i)); + + puts("\nIterate:"); + printf("%4zu: ", set.size); + c_forrange (i, int, set.size) + printf("%d", cbits_test(set, i)); + puts(""); + + c_with (cbits s2 = cbits_clone(set), cbits_del(&s2)) { + cbits_flip_all(&s2); + cbits_set(&s2, 16); + cbits_set(&s2, 17); + cbits_set(&s2, 18); + printf(" new: "); + c_forrange (i, int, s2.size) + printf("%d", cbits_test(s2, i)); + puts(""); + + printf(" xor: "); + cbits_xor(&set, s2); + c_forrange (i, int, set.size) + printf("%d", cbits_test(set, i)); + puts(""); + + cbits_set_all(&set, false); + printf("%4zu: ", set.size); + c_forrange (i, int, set.size) + printf("%d", cbits_test(set, i)); + puts(""); + } + } } \ No newline at end of file diff --git a/examples/cpque.c b/examples/cpque.c index bcff6eab..f9dc871c 100644 --- a/examples/cpque.c +++ b/examples/cpque.c @@ -27,30 +27,28 @@ PRINT_Q(cpque_imax) PRINT_Q(cpque_imix) -int main() { - cpque_imax q = cpque_imax_init(); - +int main() +{ const int data[] = {1,8,5,6,3,4,0,9,7,2}; - c_forrange (n, c_arraylen(data)) - cpque_imax_push(&q, n); - - print_cpque_imax(q); - - cpque_imin q2 = cpque_imin_init(); - cpque_imin_emplace_items(&q2, data, c_arraylen(data)); + c_withvar (cpque_imax, q) + { + c_forrange (n, c_arraylen(data)) + cpque_imax_push(&q, n); + print_cpque_imax(q); + } - print_cpque_imin(q2); + c_withvar (cpque_imin, q2) + { + cpque_imin_emplace_items(&q2, data, c_arraylen(data)); + print_cpque_imin(q2); + } // Using imix_less to compare elements. - cpque_imix q3 = cpque_imix_init(); - - c_forrange (n, c_arraylen(data)) - cpque_imix_push(&q3, n); - - print_cpque_imix(q3); - - cpque_imin_del(&q); - cpque_imax_del(&q2); - cpque_imix_del(&q3); + c_withvar (cpque_imix, q3) + { + c_forrange (n, c_arraylen(data)) + cpque_imix_push(&q3, n); + print_cpque_imix(q3); + } } \ No newline at end of file diff --git a/examples/demos.c b/examples/demos.c index e63d5660..388e3e46 100644 --- a/examples/demos.c +++ b/examples/demos.c @@ -9,29 +9,29 @@ void stringdemo1() { printf("\nSTRINGDEMO1\n"); - cstr cs = cstr_from("one-nine-three-seven-five"); - printf("%s.\n", cs.str); + c_with (cstr cs = cstr_from("one-nine-three-seven-five"), cstr_del(&cs)) + { + printf("%s.\n", cs.str); - cstr_insert(&cs, 3, "-two"); - printf("%s.\n", cs.str); + cstr_insert(&cs, 3, "-two"); + printf("%s.\n", cs.str); - cstr_erase_n(&cs, 7, 5); // -nine - printf("%s.\n", cs.str); + cstr_erase_n(&cs, 7, 5); // -nine + printf("%s.\n", cs.str); - cstr_replace(&cs, cstr_find(cs, "seven"), 5, "four"); - printf("%s.\n", cs.str); + cstr_replace(&cs, cstr_find(cs, "seven"), 5, "four"); + printf("%s.\n", cs.str); - cstr_take(&cs, cstr_from_fmt("%s *** %s", cs.str, cs.str)); - printf("%s.\n", cs.str); + cstr_take(&cs, cstr_from_fmt("%s *** %s", cs.str, cs.str)); + printf("%s.\n", cs.str); - printf("find \"four\": %s\n", cs.str + cstr_find(cs, "four")); + printf("find \"four\": %s\n", cs.str + cstr_find(cs, "four")); - // reassign: - cstr_assign(&cs, "one two three four five six seven"); - cstr_append(&cs, " eight"); - printf("append: %s\n", cs.str); - - cstr_del(&cs); + // reassign: + cstr_assign(&cs, "one two three four five six seven"); + cstr_append(&cs, " eight"); + printf("append: %s\n", cs.str); + } } @@ -40,21 +40,22 @@ using_cvec(ix, int64_t); // ix is just an example tag name. void vectordemo1() { printf("\nVECTORDEMO1\n"); - cvec_ix bignums = cvec_ix_init(); - cvec_ix_reserve(&bignums, 100); - for (size_t i = 10; i <= 100; i += 10) - cvec_ix_push_back(&bignums, i * i); + c_with (cvec_ix bignums = cvec_ix_with_capacity(100), cvec_ix_del(&bignums)) + { + cvec_ix_reserve(&bignums, 100); + for (size_t i = 10; i <= 100; i += 10) + cvec_ix_push_back(&bignums, i * i); - printf("erase - %d: %zu\n", 3, bignums.data[3]); - cvec_ix_erase_n(&bignums, 3, 1); // erase index 3 + printf("erase - %d: %zu\n", 3, bignums.data[3]); + cvec_ix_erase_n(&bignums, 3, 1); // erase index 3 - cvec_ix_pop_back(&bignums); // erase the last - cvec_ix_erase_n(&bignums, 0, 1); // erase the first + cvec_ix_pop_back(&bignums); // erase the last + cvec_ix_erase_n(&bignums, 0, 1); // erase the first - for (size_t i = 0; i < cvec_ix_size(bignums); ++i) { - printf("%zu: %zu\n", i, bignums.data[i]); + for (size_t i = 0; i < cvec_ix_size(bignums); ++i) { + printf("%zu: %zu\n", i, bignums.data[i]); + } } - cvec_ix_del(&bignums); } @@ -63,17 +64,17 @@ using_cvec_str(); void vectordemo2() { printf("\nVECTORDEMO2\n"); - cvec_str names = cvec_str_init(); - 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", names.data[1].str); - - cvec_str_sort(&names); // Sort the array - c_foreach (i, cvec_str, names) - printf("sorted: %s\n", i.ref->str); - cvec_str_del(&names); + c_withvar (cvec_str, names) { + 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", names.data[1].str); + + cvec_str_sort(&names); // Sort the array + c_foreach (i, cvec_str, names) + printf("sorted: %s\n", i.ref->str); + } } using_clist(ix, int); @@ -82,28 +83,30 @@ void listdemo1() { printf("\nLISTDEMO1\n"); clist_ix nums = clist_ix_init(), nums2 = clist_ix_init(); - 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_t it = clist_ix_begin(&nums); - clist_ix_erase_range(&nums, clist_ix_fwd(it, 5), clist_ix_fwd(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); - clist_ix_del(&nums); + c_defer (clist_ix_del(&nums), clist_ix_del(&nums2)) + { + 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_t it = clist_ix_begin(&nums); + clist_ix_erase_range(&nums, clist_ix_fwd(it, 5), clist_ix_fwd(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); + } } using_cset(i, int); diff --git a/examples/ex_gauss1.c b/examples/ex_gauss1.c index 5613d2b3..4ab9e7a3 100644 --- a/examples/ex_gauss1.c +++ b/examples/ex_gauss1.c @@ -29,30 +29,30 @@ int main() stc64_t rng = stc64_init(seed); stc64_normalf_t dist = stc64_normalf_init(Mean, StdDev); - // Create histogram map - cmap_i mhist = cmap_i_init(); - c_forrange (N) { - int index = (int) round( stc64_normalf(&rng, &dist) ); - cmap_i_emplace(&mhist, index, 0).ref->second += 1; - } - - // Transfer map to vec and sort it by map keys. - cvec_e vhist = cvec_e_init(); - c_foreach (i, cmap_i, mhist) - cvec_e_push_back(&vhist, c_make(mapval){i.ref->first, i.ref->second}); - cvec_e_sort(&vhist); - - // Print the gaussian bar chart - cstr bar = cstr_init(); - c_foreach (i, cvec_e, vhist) { - size_t n = (size_t) (i.ref->second * StdDev * Scale * 2.5 / (float)N); - if (n > 0) { - cstr_resize(&bar, n, '*'); - printf("%4d %s\n", i.ref->first, bar.str); + c_withvar (cvec_e, vhist) { + + // Create histogram map + c_withvar (cmap_i, mhist) { + c_forrange (N) { + int index = (int) round( stc64_normalf(&rng, &dist) ); + cmap_i_emplace(&mhist, index, 0).ref->second += 1; + } + + // Transfer map to vec and sort it by map keys. + c_foreach (i, cmap_i, mhist) + cvec_e_push_back(&vhist, c_make(mapval){i.ref->first, i.ref->second}); + } + cvec_e_sort(&vhist); + + // Print the gaussian bar chart + c_withvar (cstr, bar) { + c_foreach (i, cvec_e, vhist) { + size_t n = (size_t) (i.ref->second * StdDev * Scale * 2.5 / (float)N); + if (n > 0) { + cstr_resize(&bar, n, '*'); + printf("%4d %s\n", i.ref->first, bar.str); + } + } } } - // Cleanup - cstr_del(&bar); - cmap_i_del(&mhist); - cvec_e_del(&vhist); } diff --git a/examples/ex_gauss2.c b/examples/ex_gauss2.c index bd2f41bd..bcf1e200 100644 --- a/examples/ex_gauss2.c +++ b/examples/ex_gauss2.c @@ -21,22 +21,21 @@ int main() stc64_normalf_t dist = stc64_normalf_init(Mean, StdDev); // Create histogram map - csmap_i mhist = csmap_i_init(); - c_forrange (N) { - int index = (int) round( stc64_normalf(&rng, &dist) ); - csmap_i_emplace(&mhist, index, 0).ref->second += 1; - } + c_withvar (csmap_i, mhist) { + c_forrange (N) { + int index = (int) round( stc64_normalf(&rng, &dist) ); + csmap_i_emplace(&mhist, index, 0).ref->second += 1; + } - // Print the gaussian bar chart - cstr bar = cstr_init(); - c_foreach (i, csmap_i, mhist) { - size_t n = (size_t) (i.ref->second * StdDev * Scale * 2.5 / (float)N); - if (n > 0) { - cstr_resize(&bar, n, '*'); - printf("%4d %s\n", i.ref->first, bar.str); + // Print the gaussian bar chart + c_withvar (cstr, bar) { + c_foreach (i, csmap_i, mhist) { + size_t n = (size_t) (i.ref->second * StdDev * Scale * 2.5 / (float)N); + if (n > 0) { + cstr_resize(&bar, n, '*'); + printf("%4d %s\n", i.ref->first, bar.str); + } + } } } - // Cleanup - cstr_del(&bar); - csmap_i_del(&mhist); } diff --git a/examples/inits.c b/examples/inits.c index c5190e75..c1d64801 100644 --- a/examples/inits.c +++ b/examples/inits.c @@ -23,78 +23,80 @@ int main(void) { // CVEC FLOAT / PRIORITY QUEUE - cvec_f floats = cvec_f_init(); - c_emplace(cvec_f, floats, {4.0f, 2.0f, 5.0f, 3.0f, 1.0f}); + c_withvar (cvec_f, floats) { + c_emplace(cvec_f, floats, {4.0f, 2.0f, 5.0f, 3.0f, 1.0f}); - c_foreach (i, cvec_f, floats) printf("%.1f ", *i.ref); - puts(""); + c_foreach (i, cvec_f, floats) printf("%.1f ", *i.ref); + puts(""); - // CVEC PRIORITY QUEUE + // CVEC PRIORITY QUEUE - cpque_f_make_heap(&floats); - c_emplace(cpque_f, floats, {40.0f, 20.0f, 50.0f, 30.0f, 10.0f}); + cpque_f_make_heap(&floats); + c_emplace(cpque_f, floats, {40.0f, 20.0f, 50.0f, 30.0f, 10.0f}); - puts("\npop and show high priorites first:"); - while (! cpque_f_empty(floats)) { - printf("%.1f ", *cpque_f_top(&floats)); - cpque_f_pop(&floats); + puts("\npop and show high priorites first:"); + while (! cpque_f_empty(floats)) { + printf("%.1f ", *cpque_f_top(&floats)); + cpque_f_pop(&floats); + } + puts("\n"); } - puts("\n"); - cpque_f_del(&floats); // CMAP ID int year = 2020; - cmap_id idnames = cmap_id_init(); - cmap_id_emplace(&idnames, 100, "Hello"); - cmap_id_insert(&idnames, 110, cstr_from("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, i.ref->second.str); - puts(""); - cmap_id_del(&idnames); + c_withvar (cmap_id, idnames) { + cmap_id_emplace(&idnames, 100, "Hello"); + cmap_id_insert(&idnames, 110, cstr_from("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, i.ref->second.str); + puts(""); + } // CMAP CNT - cmap_cnt countries = cmap_cnt_init(); - c_emplace(cmap_cnt, countries, { - {"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_foreach (i, cmap_cnt, countries) - printf("%s: %d\n", i.ref->first.str, i.ref->second); - puts(""); - cmap_cnt_del(&countries); + c_withvar (cmap_cnt, countries) { + c_emplace(cmap_cnt, countries, { + {"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_foreach (i, cmap_cnt, countries) + printf("%s: %d\n", i.ref->first.str, i.ref->second); + puts(""); + } // CVEC PAIR - c_var (cvec_ip, pairs1, { {5, 6}, {3, 4}, {1, 2}, {7, 8} }); - cvec_ip_sort(&pairs1); + c_withvar (cvec_ip, pairs1) { + c_emplace (cvec_ip, pairs1, {{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_del(&pairs1); + c_foreach (i, cvec_ip, pairs1) + printf("(%d %d) ", i.ref->x, i.ref->y); + puts(""); + } // CLIST PAIR - c_var (clist_ip, pairs2, { {5, 6}, {3, 4}, {1, 2}, {7, 8} }); - clist_ip_sort(&pairs2); + c_withvar (clist_ip, pairs2) { + c_emplace(clist_ip, pairs2, {{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_del(&pairs2); + c_foreach (i, clist_ip, pairs2) + printf("(%d %d) ", i.ref->x, i.ref->y); + puts(""); + } } \ No newline at end of file diff --git a/examples/list.c b/examples/list.c index 4b75468d..85ebcf02 100644 --- a/examples/list.c +++ b/examples/list.c @@ -8,47 +8,46 @@ int main() { int k; const int n = 2000000; - clist_fx list = clist_fx_init(); - stc64_t rng = stc64_init(1234); - stc64_uniformf_t dist = stc64_uniformf_init(100.0f, n); - int m = 0; - c_forrange (i, int, n) - clist_fx_push_back(&list, stc64_uniformf(&rng, &dist)), ++m; - double sum = 0.0; - printf("sumarize %d:\n", m); - c_foreach (i, clist_fx, list) - sum += *i.ref; - printf("sum %f\n\n", sum); + c_withvar (clist_fx, list) { + stc64_t rng = stc64_init(1234); + stc64_uniformf_t dist = stc64_uniformf_init(100.0f, n); + int m = 0; + c_forrange (i, int, n) + clist_fx_push_back(&list, stc64_uniformf(&rng, &dist)), ++m; + double sum = 0.0; + printf("sumarize %d:\n", m); + c_foreach (i, clist_fx, list) + sum += *i.ref; + printf("sum %f\n\n", sum); - k = 0; - c_foreach (i, clist_fx, list) - if (++k <= 10) printf("%8d: %10f\n", k, *i.ref); else break; - puts("sort"); - clist_fx_sort(&list); // mergesort O(n*log n) - puts("sorted"); + k = 0; + c_foreach (i, clist_fx, list) + if (++k <= 10) printf("%8d: %10f\n", k, *i.ref); else break; + puts("sort"); + clist_fx_sort(&list); // mergesort O(n*log n) + puts("sorted"); - k = 0; - c_foreach (i, clist_fx, list) - if (++k <= 10) printf("%8d: %10f\n", k, *i.ref); else break; - puts(""); + k = 0; + c_foreach (i, clist_fx, list) + if (++k <= 10) printf("%8d: %10f\n", k, *i.ref); else break; + puts(""); - clist_fx_clear(&list); - c_emplace(clist_fx, list, {10, 20, 30, 40, 30, 50}); - c_foreach (i, clist_fx, list) printf(" %g", *i.ref); - puts(""); + clist_fx_clear(&list); + c_emplace(clist_fx, list, {10, 20, 30, 40, 30, 50}); + c_foreach (i, clist_fx, list) printf(" %g", *i.ref); + puts(""); - int removed = clist_fx_remove(&list, 30); - clist_fx_insert(&list, clist_fx_begin(&list), 5); // same as push_front() - clist_fx_push_back(&list, 500); - clist_fx_push_front(&list, 1964); - clist_fx_iter_t it = clist_fx_begin(&list); - printf("Full: "); - c_foreach (i, clist_fx, list) - printf(" %g", *i.ref); - printf("\nSubs: "); - c_foreach (i, clist_fx, clist_fx_fwd(it, 4), clist_fx_end(&list)) - printf(" %g", *i.ref); - puts(""); - - clist_fx_del(&list); + int removed = clist_fx_remove(&list, 30); + clist_fx_insert(&list, clist_fx_begin(&list), 5); // same as push_front() + clist_fx_push_back(&list, 500); + clist_fx_push_front(&list, 1964); + clist_fx_iter_t it = clist_fx_begin(&list); + printf("Full: "); + c_foreach (i, clist_fx, list) + printf(" %g", *i.ref); + printf("\nSubs: "); + c_foreach (i, clist_fx, clist_fx_fwd(it, 4), clist_fx_end(&list)) + printf(" %g", *i.ref); + puts(""); + } } \ No newline at end of file diff --git a/examples/list_erase.c b/examples/list_erase.c index 45947dee..d61edace 100644 --- a/examples/list_erase.c +++ b/examples/list_erase.c @@ -6,19 +6,19 @@ using_clist(i, int); int main () { - c_var (clist_i, L, {10, 20, 30, 40, 50}); - // 10 20 30 40 50 - clist_i_iter_t it = clist_i_begin(&L); // ^ - clist_i_next(&it); - it = clist_i_erase_at(&L, it); // 10 30 40 50 - // ^ - clist_i_iter_t end = clist_i_end(&L); // - clist_i_next(&it); - it = clist_i_erase_range(&L, it, end); // 10 30 - // ^ - printf("mylist contains:"); - c_foreach (x, clist_i, L) printf(" %d", *x.ref); - puts(""); - - clist_i_del(&L); + c_withvar (clist_i, L) { + c_emplace(clist_i, L, {10, 20, 30, 40, 50}); + // 10 20 30 40 50 + clist_i_iter_t it = clist_i_begin(&L); // ^ + clist_i_next(&it); + it = clist_i_erase_at(&L, it); // 10 30 40 50 + // ^ + clist_i_iter_t end = clist_i_end(&L); // + clist_i_next(&it); + it = clist_i_erase_range(&L, it, end); // 10 30 + // ^ + printf("mylist contains:"); + c_foreach (x, clist_i, L) printf(" %d", *x.ref); + puts(""); + } } diff --git a/examples/list_splice.c b/examples/list_splice.c index b8efa5db..dd5d8cc4 100644 --- a/examples/list_splice.c +++ b/examples/list_splice.c @@ -14,21 +14,21 @@ void print_ilist(const char* s, clist_i list) int main () { - c_var (clist_i, list1, { 1, 2, 3, 4, 5 }); - c_var (clist_i, list2, { 10, 20, 30, 40, 50 }); - - clist_i_iter_t it = clist_i_fwd(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_del(clist_i, &list1, &list2); + c_var (clist_i, list1, {1, 2, 3, 4, 5}); + c_var (clist_i, list2, {10, 20, 30, 40, 50}); + c_defer (clist_i_del(&list1), clist_i_del(&list2)) + { + clist_i_iter_t it = clist_i_fwd(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); + } } \ No newline at end of file diff --git a/examples/mapmap.c b/examples/mapmap.c index fc6c8a79..b4bb6beb 100644 --- a/examples/mapmap.c +++ b/examples/mapmap.c @@ -9,20 +9,19 @@ using_cmap_str(); using_cmap_strkey(cfg, cmap_str, cmap_str_del, c_no_clone); int main(void) { - cmap_cfg cfg = cmap_cfg_init(); - cmap_str init = cmap_str_init(); - cmap_str_emplace(&cmap_cfg_insert(&cfg, cstr_from("user"), init).ref->second, "name", "Joe"); - cmap_str_emplace(&cmap_cfg_insert(&cfg, cstr_from("user"), init).ref->second, "groups", "proj1,proj3"); - cmap_str_emplace(&cmap_cfg_insert(&cfg, cstr_from("group"), init).ref->second, "proj1", "Energy"); - cmap_str_emplace(&cmap_cfg_insert(&cfg, cstr_from("group"), init).ref->second, "proj2", "Windy"); - cmap_str_emplace(&cmap_cfg_insert(&cfg, cstr_from("group"), init).ref->second, "proj3", "Oil"); - cmap_str_emplace(&cmap_cfg_insert(&cfg, cstr_from("admin"), init).ref->second, "employees", "2302"); + c_withvar (cmap_cfg, cfg) { + cmap_str init = cmap_str_init(); + cmap_str_emplace(&cmap_cfg_insert(&cfg, cstr_from("user"), init).ref->second, "name", "Joe"); + cmap_str_emplace(&cmap_cfg_insert(&cfg, cstr_from("user"), init).ref->second, "groups", "proj1,proj3"); + cmap_str_emplace(&cmap_cfg_insert(&cfg, cstr_from("group"), init).ref->second, "proj1", "Energy"); + cmap_str_emplace(&cmap_cfg_insert(&cfg, cstr_from("group"), init).ref->second, "proj2", "Windy"); + cmap_str_emplace(&cmap_cfg_insert(&cfg, cstr_from("group"), init).ref->second, "proj3", "Oil"); + cmap_str_emplace(&cmap_cfg_insert(&cfg, cstr_from("admin"), init).ref->second, "employees", "2302"); - cmap_str_emplace_or_assign(&cmap_cfg_insert(&cfg, cstr_from("group"), init).ref->second, "proj2", "Wind"); // Update + cmap_str_emplace_or_assign(&cmap_cfg_insert(&cfg, cstr_from("group"), init).ref->second, "proj2", "Wind"); // Update - c_foreach (i, cmap_cfg, cfg) - c_foreach (j, cmap_str, i.ref->second) - printf("%s: %s - %s (%u)\n", i.ref->first.str, j.ref->first.str, j.ref->second.str, i.ref->second.bucket_count); - - cmap_cfg_del(&cfg); + c_foreach (i, cmap_cfg, cfg) + c_foreach (j, cmap_str, i.ref->second) + printf("%s: %s - %s (%u)\n", i.ref->first.str, j.ref->first.str, j.ref->second.str, i.ref->second.bucket_count); + } } \ No newline at end of file diff --git a/examples/olympics.c b/examples/olympics.c index 2c4cc270..07388c1b 100644 --- a/examples/olympics.c +++ b/examples/olympics.c @@ -54,24 +54,23 @@ using_csmap_strkey(ol, clist_ol, clist_ol_del, c_no_clone); int main() { - csmap_ol multimap = csmap_ol_init(); - clist_ol empty = clist_ol_init(); + c_withvar (csmap_ol, multimap) { + clist_ol empty = clist_ol_init(); - for (int i = 0; iyear, .city=cstr_from(it->city), .date=cstr_from(it->date)}; - // Insert an empty list for each new country, and append the entry to the list. - // If list already exist in map, it returns it from the insert function. - clist_ol_push_back(&csmap_ol_insert(&multimap, cstr_from(it->country), empty).ref->second, loc); - } + for (int i = 0; iyear, .city=cstr_from(it->city), .date=cstr_from(it->date)}; + // Insert an empty list for each new country, and append the entry to the list. + // If list already exist in map, it returns it from the insert function. + clist_ol_push_back(&csmap_ol_insert(&multimap, cstr_from(it->country), empty).ref->second, loc); + } - c_foreach (country, csmap_ol, multimap) { - clist_ol_sort(&country.ref->second); // Sort locations by year for each country. - c_foreach (loc, clist_ol, country.ref->second) - printf("%s: %d, %s, %s\n", country.ref->first.str, loc.ref->year, - loc.ref->city.str, - loc.ref->date.str); + c_foreach (country, csmap_ol, multimap) { + clist_ol_sort(&country.ref->second); // Sort locations by year for each country. + c_foreach (loc, clist_ol, country.ref->second) + printf("%s: %d, %s, %s\n", country.ref->first.str, loc.ref->year, + loc.ref->city.str, + loc.ref->date.str); + } } - // cleanup everything - csmap_ol_del(&multimap); } diff --git a/examples/phonebook.c b/examples/phonebook.c index 335679e3..40a4b0fd 100644 --- a/examples/phonebook.c +++ b/examples/phonebook.c @@ -39,40 +39,43 @@ int main(int argc, char **argv) { c_static_assert(3 == 3, "hello"); - c_var (cset_str, names, {"Hello", "Cool", "True"}); - c_foreach (i, cset_str, names) printf("set: %s\n", i.ref->str); + c_withvar (cset_str, names) { + c_emplace (cset_str, names, {"Hello", "Cool", "True"}); + c_foreach (i, cset_str, names) printf("%s ", i.ref->str); + puts(""); + } bool erased; - c_var (cmap_str, phone_book, { - {"Lilia Friedman", "(892) 670-4739"}, - {"Tariq Beltran", "(489) 600-7575"}, - {"Laiba Juarez", "(303) 885-5692"}, - {"Elliott Mooney", "(945) 616-4482"}, - }); + c_withvar (cmap_str, phone_book) { + c_emplace (cmap_str, phone_book, { + {"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); + 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"); + 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); + printf("\nPhone book after adding Zak Byers:\n"); + print_phone_book(phone_book); - if (cmap_str_find(&phone_book, "Tariq Beltran").ref != NULL) - printf("\nTariq Beltran is in phone book\n"); + if (cmap_str_find(&phone_book, "Tariq Beltran").ref != NULL) + printf("\nTariq Beltran is in phone book\n"); - erased = cmap_str_erase(&phone_book, "Tariq Beltran"); - erased = cmap_str_erase(&phone_book, "Elliott Mooney"); + erased = cmap_str_erase(&phone_book, "Tariq Beltran"); + erased = cmap_str_erase(&phone_book, "Elliott Mooney"); - printf("\nPhone book after erasing Tariq and Elliott:\n"); - print_phone_book(phone_book); + 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"); + 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_del(&phone_book); + printf("\nPhone book after update phone of Zak Byers:\n"); + print_phone_book(phone_book); + } puts("done"); } \ No newline at end of file diff --git a/examples/prime.c b/examples/prime.c index 5c6b5065..48fa5bbe 100644 --- a/examples/prime.c +++ b/examples/prime.c @@ -27,15 +27,14 @@ int main(void) printf("computing prime numbers up to %zu\n", n); clock_t t1 = clock(); - cbits primes = sieveOfEratosthenes(n + 1); - size_t np = cbits_count(primes); - clock_t t2 = clock(); + c_with (cbits primes = sieveOfEratosthenes(n + 1), cbits_del(&primes)) { + size_t np = cbits_count(primes); + clock_t t2 = clock(); - printf("number of primes: %zu, time: %f\n", np, (t2 - t1) / (float)CLOCKS_PER_SEC); + printf("number of primes: %zu, time: %f\n", np, (t2 - t1) / (float)CLOCKS_PER_SEC); - printf(" 2"); for (size_t i = 3; i < 1000; i += 2) - if (cbits_test(primes, i>>1)) printf(" %zu", i); - puts(""); - - cbits_del(&primes); + printf(" 2"); for (size_t i = 3; i < 1000; i += 2) + if (cbits_test(primes, i>>1)) printf(" %zu", i); + puts(""); + } } diff --git a/examples/priority.c b/examples/priority.c index ec26cb15..d0234dbc 100644 --- a/examples/priority.c +++ b/examples/priority.c @@ -13,23 +13,22 @@ int main() { size_t N = 10000000; stc64_t rng = stc64_init(time(NULL)); stc64_uniform_t dist = stc64_uniform_init(0, N * 10); - cpque_i heap = cpque_i_init(); - - // Push ten million random numbers to priority queue - c_forrange (N) - cpque_i_push(&heap, stc64_uniform(&rng, &dist)); - - // push some negative numbers too. - c_emplace(cpque_i, heap, {-231, -32, -873, -4, -343}); - - c_forrange (N) - cpque_i_push(&heap, stc64_uniform(&rng, &dist)); - - - // Extract the hundred smallest. - c_forrange (100) { - printf("%zd ", *cpque_i_top(&heap)); - cpque_i_pop(&heap); + c_withvar (cpque_i, heap) + { + // Push ten million random numbers to priority queue + c_forrange (N) + cpque_i_push(&heap, stc64_uniform(&rng, &dist)); + + // push some negative numbers too. + c_emplace(cpque_i, heap, {-231, -32, -873, -4, -343}); + + c_forrange (N) + cpque_i_push(&heap, stc64_uniform(&rng, &dist)); + + // Extract the hundred smallest. + c_forrange (100) { + printf("%zd ", *cpque_i_top(&heap)); + cpque_i_pop(&heap); + } } - cpque_i_del(&heap); } diff --git a/examples/queue.c b/examples/queue.c index 23640a39..e3a74f33 100644 --- a/examples/queue.c +++ b/examples/queue.c @@ -17,21 +17,21 @@ int main() { stc64_t rng = stc64_init(1234); dist = stc64_uniform_init(0, n); - cqueue_i queue = cqueue_i_init(); + c_withvar (cqueue_i, queue) + { + // Push ten million random numbers onto the queue. + c_forrange (n) + cqueue_i_push(&queue, stc64_uniform(&rng, &dist)); - // Push ten million random numbers onto the queue. - c_forrange (n) - cqueue_i_push(&queue, stc64_uniform(&rng, &dist)); - - // Push or pop on the queue ten million times - printf("%d\n", n); - c_forrange (n) { // range uses initial n only. - int r = stc64_uniform(&rng, &dist); - if (r & 1) - ++n, cqueue_i_push(&queue, r); - else - --n, cqueue_i_pop(&queue); + // Push or pop on the queue ten million times + printf("%d\n", n); + c_forrange (n) { // range uses initial n only. + int r = stc64_uniform(&rng, &dist); + if (r & 1) + ++n, cqueue_i_push(&queue, r); + else + --n, cqueue_i_pop(&queue); + } + printf("%d, %zu\n", n, cqueue_i_size(queue)); } - printf("%d, %zu\n", n, cqueue_i_size(queue)); - cqueue_i_del(&queue); } diff --git a/examples/replace.c b/examples/replace.c index fdf5a7df..b537ef88 100644 --- a/examples/replace.c +++ b/examples/replace.c @@ -3,31 +3,30 @@ int main () { - const char *base = "this is a test string."; - const char *s2 = "n example"; - const char *s3 = "sample phrase"; - const char *s4 = "useful."; + const char *base = "this is a test string."; + const char *s2 = "n example"; + const char *s3 = "sample phrase"; + const char *s4 = "useful."; - // replace signatures used in the same order as described above: + // 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, m.str); - cstr_append(&m, m.str); - printf("%s\n", m.str); - - cstr_replace(&s, 9, 5, s2); // "this is an example string." (1) - printf("(1) %s\n", s.str); - cstr_replace_n(&s, 19, 6, s3+7, 6); // "this is an example phrase." (2) - printf("(2) %s\n", s.str); - cstr_replace(&s, 8, 10, "just a"); // "this is just a phrase." (3) - printf("(3) %s\n", s.str); - cstr_replace_n(&s, 8, 6,"a shorty", 7); // "this is a short phrase." (4) - printf("(4) %s\n", s.str); - cstr_replace(&s, 22, 1, "!!!"); // "this is a short phrase!!!" (5) - printf("(5) %s\n", s.str); - - c_del(cstr, &s, &m); // destroy + // Ustring positions: 0123456789*123456789*12345 + cstr s = cstr_from(base); // "this is a test string." + cstr m = cstr_clone(s); + c_defer (cstr_del(&s), cstr_del(&m)) { + cstr_append(&m, m.str); + cstr_append(&m, m.str); + printf("%s\n", m.str); + + cstr_replace(&s, 9, 5, s2); // "this is an example string." (1) + printf("(1) %s\n", s.str); + cstr_replace_n(&s, 19, 6, s3+7, 6); // "this is an example phrase." (2) + printf("(2) %s\n", s.str); + cstr_replace(&s, 8, 10, "just a"); // "this is just a phrase." (3) + printf("(3) %s\n", s.str); + cstr_replace_n(&s, 8, 6,"a shorty", 7); // "this is a short phrase." (4) + printf("(4) %s\n", s.str); + cstr_replace(&s, 22, 1, "!!!"); // "this is a short phrase!!!" (5) + printf("(5) %s\n", s.str); + } } diff --git a/examples/stack.c b/examples/stack.c index 3bcf05dd..0815b580 100644 --- a/examples/stack.c +++ b/examples/stack.c @@ -11,17 +11,19 @@ using_cstack(c, cvec_c); int main() { cstack_i stack = cstack_i_init(); cstack_c chars = cstack_c_init(); + c_defer (cstack_i_del(&stack), cstack_c_del(&chars)) + { + c_forrange (i, int, 101) + cstack_i_push(&stack, i*i); - c_forrange (i, int, 101) - cstack_i_push(&stack, i*i); + printf("%d\n", *cstack_i_top(&stack)); - printf("%d\n", *cstack_i_top(&stack)); - - c_forrange (i, int, 90) - cstack_i_pop(&stack); - - c_foreach (i, cstack_i, stack) - printf(" %d", *i.ref); - puts(""); - printf("top: %d\n", *cstack_i_top(&stack)); + c_forrange (i, int, 90) + cstack_i_pop(&stack); + + c_foreach (i, cstack_i, stack) + printf(" %d", *i.ref); + puts(""); + printf("top: %d\n", *cstack_i_top(&stack)); + } } \ No newline at end of file diff --git a/examples/stc_astar.c b/examples/stc_astar.c index 90ef6e44..11e8ca2b 100644 --- a/examples/stc_astar.c +++ b/examples/stc_astar.c @@ -77,55 +77,57 @@ astar(cstr maze, int width) { MazePoint start = mpnt_from(maze, "@", width); MazePoint goal = mpnt_from(maze, "!", width); + + cdeq_pnt path = cdeq_pnt_init(); // returned + cpque_pnt frontier = cpque_pnt_init(); csmap_step came_from = csmap_step_init(); csmap_cost cost_so_far = csmap_cost_init(); - - cpque_pnt_push(&frontier, start); - csmap_cost_insert(&cost_so_far, start, 0); - - while (!cpque_pnt_empty(frontier)) + c_defer (cpque_pnt_del(&frontier), + csmap_step_del(&came_from), + csmap_cost_del(&cost_so_far)) { - MazePoint current = *cpque_pnt_top(&frontier); - cpque_pnt_pop(&frontier); - if (mpnt_equal(¤t, &goal)) - break; - MazePoint 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 }, - }; - - c_forrange (i, c_arraylen(deltas)) + cpque_pnt_push(&frontier, start); + csmap_cost_insert(&cost_so_far, start, 0); + + while (!cpque_pnt_empty(frontier)) { - MazePoint delta = deltas[i]; - MazePoint next = mpnt_init(current.x + delta.x, current.y + delta.y, width); - int new_cost = *csmap_cost_at(&cost_so_far, current); - if (maze.str[mpnt_index(&next)] != '#') + MazePoint current = *cpque_pnt_top(&frontier); + cpque_pnt_pop(&frontier); + if (mpnt_equal(¤t, &goal)) + break; + MazePoint 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 }, + }; + + c_forrange (i, c_arraylen(deltas)) { - csmap_cost_value_t* cost = csmap_cost_find(&cost_so_far, next).ref; - if (!cost || new_cost < cost->second) + MazePoint delta = deltas[i]; + MazePoint next = mpnt_init(current.x + delta.x, current.y + delta.y, width); + int new_cost = *csmap_cost_at(&cost_so_far, current); + if (maze.str[mpnt_index(&next)] != '#') { - csmap_cost_put(&cost_so_far, next, new_cost); // update - next.priorty = new_cost + abs(goal.x - next.x) + abs(goal.y - next.y); - cpque_pnt_push(&frontier, next); - csmap_step_put(&came_from, next, current); + csmap_cost_value_t* cost = csmap_cost_find(&cost_so_far, next).ref; + if (!cost || new_cost < cost->second) + { + csmap_cost_put(&cost_so_far, next, new_cost); // update + next.priorty = new_cost + abs(goal.x - next.x) + abs(goal.y - next.y); + cpque_pnt_push(&frontier, next); + csmap_step_put(&came_from, next, current); + } } } } + MazePoint current = goal; + while(!mpnt_equal(¤t, &start)) + { + cdeq_pnt_push_front(&path, current); + current = *csmap_step_at(&came_from, current); + } + cdeq_pnt_push_front(&path, start); } - MazePoint current = goal; - cdeq_pnt path = cdeq_pnt_init(); - - while(!mpnt_equal(¤t, &start)) - { - cdeq_pnt_push_front(&path, current); - current = *csmap_step_at(&came_from, current); - } - cdeq_pnt_push_front(&path, start); - cpque_pnt_del(&frontier); - csmap_step_del(&came_from); - csmap_cost_del(&cost_so_far); return path; } diff --git a/examples/svmap.c b/examples/svmap.c index f4bcc311..9fd89755 100644 --- a/examples/svmap.c +++ b/examples/svmap.c @@ -9,26 +9,26 @@ int main() { csview fox = c_sv("The quick brown fox jumps over the lazy dog."); printf("\"%s\", length=%zu\n", fox.str, fox.size); - cmap_si frequencies = cmap_si_init(); - - // Non-emplace: cstr element API - cmap_si_insert(&frequencies, cstr_new("thousand"), 1000); - cmap_si_insert_or_assign(&frequencies, cstr_new("thousand"), 2000); // update; same as put() - cmap_si_insert(&frequencies, cstr_new("thousand"), 3000); // ignored - - // Emplace: csview element API - const char* key = "hundred"; - cmap_si_emplace(&frequencies, c_sv("hundred"), 300); // c_sv() shorthand for csview_new() - cmap_si_emplace(&frequencies, csview_from_n(key, 4), 400); // insert "hund" - cmap_si_emplace_or_assign(&frequencies, csview_from(key), 500); // update - cmap_si_emplace(&frequencies, c_sv("hundred"), 600); // ignored, already inserted - - // Lookup always uses "raw" type API, i.e. csview here. - printf("at(\"hundred\"): %d\n", *cmap_si_at(&frequencies, c_sv("hundred"))); - - c_foreach (i, cmap_si, frequencies) - printf("%s: %d\n", i.ref->first.str, i.ref->second); - + c_withvar (cmap_si, frequencies) + { + // Non-emplace: cstr element API + cmap_si_insert(&frequencies, cstr_new("thousand"), 1000); + cmap_si_insert_or_assign(&frequencies, cstr_new("thousand"), 2000); // update; same as put() + cmap_si_insert(&frequencies, cstr_new("thousand"), 3000); // ignored + + // Emplace: csview element API + const char* key = "hundred"; + cmap_si_emplace(&frequencies, c_sv("hundred"), 300); // c_sv() shorthand for csview_new() + cmap_si_emplace(&frequencies, csview_from_n(key, 4), 400); // insert "hund" + cmap_si_emplace_or_assign(&frequencies, csview_from(key), 500); // update + cmap_si_emplace(&frequencies, c_sv("hundred"), 600); // ignored, already inserted + + // Lookup always uses "raw" type API, i.e. csview here. + printf("at(\"hundred\"): %d\n", *cmap_si_at(&frequencies, c_sv("hundred"))); + + c_foreach (i, cmap_si, frequencies) + printf("%s: %d\n", i.ref->first.str, i.ref->second); + } /* Output: */ // "The quick brown fox jumps over the lazy dog.", length=44 // at("hundred"): 500 diff --git a/examples/words.c b/examples/words.c index 1edb1483..6859f104 100644 --- a/examples/words.c +++ b/examples/words.c @@ -15,27 +15,28 @@ int main1() "this", "sentence", "is", "not", "a", "sentence", "this", "sentence", "is", "a", "hoax" }); + c_defer (clist_str_del(&lwords)) + { + clist_str_push_back(&lwords, cstr_from_fmt("%.15f", sqrt(2))); + c_foreach (w, clist_str, lwords) + printf("%s\n", w.ref->str); + puts(""); - clist_str_push_back(&lwords, cstr_from_fmt("%.15f", sqrt(2))); - c_foreach (w, clist_str, lwords) - printf("%s\n", w.ref->str); - puts(""); + c_var (cvec_str, words, { + "this", "sentence", "is", "not", "a", "sentence", + "this", "sentence", "is", "a", "hoax" + }); + c_defer (cvec_str_del(&words)) + { + cmap_si word_map = cmap_si_init(); + c_foreach (w, cvec_str, words) + cmap_si_emplace(&word_map, w.ref->str, 0).ref->second += 1; - c_var (cvec_str, words, { - "this", "sentence", "is", "not", "a", "sentence", - "this", "sentence", "is", "a", "hoax" - }); - - cmap_si word_map = cmap_si_init(); - c_foreach (w, cvec_str, words) - cmap_si_emplace(&word_map, w.ref->str, 0).ref->second += 1; - - c_foreach (i, cmap_si, word_map) { - printf("%d occurrences of word '%s'\n", i.ref->second, i.ref->first.str); + c_foreach (i, cmap_si, word_map) { + printf("%d occurrences of word '%s'\n", i.ref->second, i.ref->first.str); + } + } } - - cmap_si_del(&word_map); - cvec_str_del(&words); return 0; } diff --git a/stc/carray.h b/stc/carray.h index 8bfe6fe1..e3859b8a 100644 --- a/stc/carray.h +++ b/stc/carray.h @@ -33,22 +33,21 @@ using_carray2(i, int); int main() { int w = 7, h = 5; - carray2i image = carray2i_init(w, h); - - int *dat = carray2i_data(&image); - for (int i = 0; i < carray2i_size(image); ++i) - dat[i] = i; - - for (int x = 0; x < image.xdim; ++x) - for (int y = 0; y < image.ydim; ++y) - printf(" %d", image.data[x][y]); - puts("\n"); - - c_foreach (i, carray2i, image) - printf(" %d", *i.ref); - puts(""); - - carray2i_del(&image); + c_with (carray2i image = carray2i_init(w, h), carray2i_del(&image)) + { + int *dat = carray2i_data(&image); + for (int i = 0; i < carray2i_size(image); ++i) + dat[i] = i; + + for (int x = 0; x < image.xdim; ++x) + for (int y = 0; y < image.ydim; ++y) + printf(" %d", image.data[x][y]); + puts("\n"); + + c_foreach (i, carray2i, image) + printf(" %d", *i.ref); + puts(""); + } } */ diff --git a/stc/cbits.h b/stc/cbits.h index 35f3f161..fc2d525b 100644 --- a/stc/cbits.h +++ b/stc/cbits.h @@ -30,25 +30,26 @@ Similar to boost::dynamic_bitset / std::bitset #include "cbits.h" int main() { - cbits bset = cbits_with_size(23, true); - cbits_reset(&bset, 9); - cbits_resize(&bset, 43, false); - - printf("%4zu: ", bset.size); - c_forrange (i, bset.size) - printf("%d", cbits_at(&bset, i)); - puts(""); - cbits_set(&bset, 28); - cbits_resize(&bset, 77, true); - cbits_resize(&bset, 93, false); - cbits_resize(&bset, 102, true); - cbits_set_value(&bset, 99, false); - - printf("%4zu: ", bset.size); - c_forrange (i, bset.size) - printf("%d", cbits_at(&bset, i)); - puts(""); - cbits_del(&bset); + c_with (cbits bset = cbits_with_size(23, true), cbits_del(&bset)) + { + cbits_reset(&bset, 9); + cbits_resize(&bset, 43, false); + + printf("%4zu: ", bset.size); + c_forrange (i, bset.size) + printf("%d", cbits_at(&bset, i)); + puts(""); + cbits_set(&bset, 28); + cbits_resize(&bset, 77, true); + cbits_resize(&bset, 93, false); + cbits_resize(&bset, 102, true); + cbits_set_value(&bset, 99, false); + + printf("%4zu: ", bset.size); + c_forrange (i, bset.size) + printf("%d", cbits_at(&bset, i)); + puts(""); + } } */ #include diff --git a/stc/ccommon.h b/stc/ccommon.h index 0fa74f7b..7e73dc5f 100644 --- a/stc/ccommon.h +++ b/stc/ccommon.h @@ -122,9 +122,12 @@ for (type i=start, i##_inc_=step, i##_end_=(stop) - (0 < i##_inc_) \ ; (i <= i##_end_) == (0 < i##_inc_); i += i##_inc_) -#define c_with(start, end) for (start, *_c_w = NULL; !_c_w; ++_c_w, end) -#define c_withbuffer(b, type, n) c_withbuffer_x(b, type, n, 256) -#define c_withbuffer_x(b, type, n, BYTES) \ +#define c_defer(...) for (int _c_ii = 0; !_c_ii; ++_c_ii, __VA_ARGS__) +#define c_with(start, end) for (start, *_c_ii = NULL; !_c_ii; ++_c_ii, end) +#define c_withvar(ctype, var) c_with (ctype var = ctype##_init(), ctype##_del(&var)) + +#define c_withbuf(b, type, n) c_withbuf_N(b, type, n, 256) +#define c_withbuf_N(b, type, n, BYTES) \ for (type _c_b[((BYTES) - 1) / sizeof(type) + 1], \ *b = (n)*sizeof *b > (BYTES) ? c_new_n(type, n) : _c_b \ ; b; b != _c_b ? c_free(b) : (void)0, b = NULL) diff --git a/stc/clist.h b/stc/clist.h index 7a39081c..dd7ecc12 100644 --- a/stc/clist.h +++ b/stc/clist.h @@ -35,21 +35,22 @@ using_clist(ix, int64_t); int main() { - clist_ix list = clist_ix_init(); - stc64_t rng = stc64_init(12345); - int n; - for (int i=0; i<1000000; ++i) // one million - clist_ix_push_back(&list, stc64_rand(&rng) >> 32); - n = 0; - c_foreach (i, clist_ix, list) - if (++n % 10000 == 0) printf("%8d: %10zd\n", n, i.ref->value); - // Sort them... - clist_ix_sort(&list); // mergesort O(n*log n) - n = 0; - puts("sorted"); - c_foreach (i, clist_ix, list) - if (++n % 10000 == 0) printf("%8d: %10zd\n", n, i.ref->value); - clist_ix_del(&list); + c_withvar (clist_ix, list) + { + stc64_t rng = stc64_init(12345); + int n; + for (int i=0; i<1000000; ++i) // one million + clist_ix_push_back(&list, stc64_rand(&rng) >> 32); + n = 0; + c_foreach (i, clist_ix, list) + if (++n % 10000 == 0) printf("%8d: %10zd\n", n, i.ref->value); + // Sort them... + clist_ix_sort(&list); // mergesort O(n*log n) + n = 0; + puts("sorted"); + c_foreach (i, clist_ix, list) + if (++n % 10000 == 0) printf("%8d: %10zd\n", n, i.ref->value); + } } */ #include "ccommon.h" diff --git a/stc/cmap.h b/stc/cmap.h index d9fd787c..a6dbd7cc 100644 --- a/stc/cmap.h +++ b/stc/cmap.h @@ -31,19 +31,20 @@ using_cmap(mx, int, char); // Map of int -> char int main(void) { - cmap_mx m = cmap_mx_init(); - cmap_mx_emplace(&m, 5, 'a'); - cmap_mx_emplace(&m, 8, 'b'); - cmap_mx_emplace(&m, 12, 'c'); - - cmap_mx_iter_t it = cmap_mx_find(&m, 10); // none - char val = cmap_mx_find(&m, 5).ref->second; - cmap_mx_emplace_or_assign(&m, 5, 'd'); // update - cmap_mx_erase(&m, 8); - - c_foreach (i, cmap_mx, m) - printf("map %d: %c\n", i.ref->first, i.ref->second); - cmap_mx_del(&m); + c_withvar (cmap_mx, m) + { + cmap_mx_emplace(&m, 5, 'a'); + cmap_mx_emplace(&m, 8, 'b'); + cmap_mx_emplace(&m, 12, 'c'); + + cmap_mx_iter_t it = cmap_mx_find(&m, 10); // none + char val = cmap_mx_find(&m, 5).ref->second; + cmap_mx_emplace_or_assign(&m, 5, 'd'); // update + cmap_mx_erase(&m, 8); + + c_foreach (i, cmap_mx, m) + printf("map %d: %c\n", i.ref->first, i.ref->second); + } } */ #include "ccommon.h" diff --git a/stc/cpque.h b/stc/cpque.h index 680cc6c6..f6fa67a2 100644 --- a/stc/cpque.h +++ b/stc/cpque.h @@ -32,16 +32,18 @@ stc64_t rng = stc64_init(1234); stc64_uniformf_t dist = stc64_uniformf_init(10.0f, 100.0f); - cpque_f queue = cpque_f_init(); - // Push ten million random numbers onto the queue. - for (int i=0; i<10000000; ++i) - cpque_f_push(&queue, stc64_uniformf(&rng, dist)); - // Extract the 100 smallest. - for (int i=0; i<100; ++i) { - printf("%f ", *cpque_f_top(queue)); - cpque_f_pop(&queue); + c_withvar (cpque_f, queue) + { + // Push ten million random numbers onto the queue. + for (int i=0; i<10000000; ++i) + cpque_f_push(&queue, stc64_uniformf(&rng, dist)); + + // Extract the 100 smallest. + for (int i=0; i<100; ++i) { + printf("%f ", *cpque_f_top(queue)); + cpque_f_pop(&queue); + } } - cpque_f_del(&queue); } */ #ifndef CPQUEUE_H_INCLUDED diff --git a/stc/cqueue.h b/stc/cqueue.h index 046ed2fb..af6cc7a2 100644 --- a/stc/cqueue.h +++ b/stc/cqueue.h @@ -35,23 +35,23 @@ stc64_t rng = stc64_init(1234); stc64_uniform_t dist = stc64_uniform_init(rng, 0, n); - cqueue_i queue = cqueue_i_init(); + c_withvar (cqueue_i, queue) + { + // Push ten million random numbers onto the queue. + for (int i=0; i0; --i) { - int r = stc64_uniform(&dist); - if (r & 1) - ++n, cqueue_i_push(&queue, r); - else - --n, cqueue_i_pop(&queue); + // Push or pop on the queue ten million times + printf("%d\n", n); + for (int i=n; i>0; --i) { + int r = stc64_uniform(&dist); + if (r & 1) + ++n, cqueue_i_push(&queue, r); + else + --n, cqueue_i_pop(&queue); + } } printf("%d\n", n); - cqueue_i_del(&queue); } */ #include "cdeq.h" diff --git a/stc/csmap.h b/stc/csmap.h index 60c3afc0..5c2aac0f 100644 --- a/stc/csmap.h +++ b/stc/csmap.h @@ -30,19 +30,20 @@ using_csmap(mx, int, char); // Sorted map int main(void) { - csmap_mx m = csmap_mx_init(); - csmap_mx_insert(&m, 5, 'a'); - csmap_mx_insert(&m, 8, 'b'); - csmap_mx_insert(&m, 12, 'c'); + c_withvar (csmap_mx, m) + { + csmap_mx_insert(&m, 5, 'a'); + csmap_mx_insert(&m, 8, 'b'); + csmap_mx_insert(&m, 12, 'c'); - csmap_mx_iter_t it = csmap_mx_find(&m, 10); // none - char val = csmap_mx_find(&m, 5).ref->second; - csmap_mx_put(&m, 5, 'd'); // update - csmap_mx_erase(&m, 8); + csmap_mx_iter_t it = csmap_mx_find(&m, 10); // none + char val = csmap_mx_find(&m, 5).ref->second; + csmap_mx_put(&m, 5, 'd'); // update + csmap_mx_erase(&m, 8); - c_foreach (i, csmap_mx, m) - printf("map %d: %c\n", i.ref->first, i.ref->second); - csmap_mx_del(&m); + c_foreach (i, csmap_mx, m) + printf("map %d: %c\n", i.ref->first, i.ref->second); + } } */ #include "ccommon.h" diff --git a/stc/cstack.h b/stc/cstack.h index 7934fbbe..3a5f491c 100644 --- a/stc/cstack.h +++ b/stc/cstack.h @@ -32,15 +32,16 @@ using_cstack(i, cvec_i); int main() { - cstack_i stack = cstack_i_init(); + c_withvar (cstack_i, stack) + { + for (int i=0; i<100; ++i) + cstack_i_push(&stack, i*i); - for (int i=0; i<100; ++i) - cstack_i_push(&stack, i*i); + for (int i=0; i<90; ++i) + cstack_i_pop(&stack); - for (int i=0; i<90; ++i) - cstack_i_pop(&stack); - - printf("top: %d\n", *cstack_i_top(&stack)); + printf("top: %d\n", *cstack_i_top(&stack)); + } } */ #include "cvec.h" diff --git a/stc/cstr.h b/stc/cstr.h index 4497d1a9..4e70189a 100644 --- a/stc/cstr.h +++ b/stc/cstr.h @@ -305,7 +305,7 @@ STC_DEF void cstr_replace_n(cstr* self, size_t pos, size_t len, const char* str, size_t n) { size_t sz = cstr_size(*self); if (len > sz - pos) len = sz - pos; - c_withbuffer (xstr, char, n) { + c_withbuf (xstr, char, n) { memcpy(xstr, str, n); _cstr_internal_move(self, pos + len, pos + n); memcpy(&self->str[pos], xstr, n); -- cgit v1.2.3