diff options
82 files changed, 1954 insertions, 2135 deletions
@@ -3,7 +3,7 @@ STC - Smart Template Containers for C ===================================== -News: Version 4.1.1 Released (Feb 2023) +News: Version 4.2 Released (2023-03-26) ------------------------------------------------ I am happy to finally announce a new release! Major changes: - A new exciting [**cspan**](docs/cspan_api.md) single/multi-dimensional array view (with numpy-like slicing). @@ -148,108 +148,138 @@ The usage of the containers is similar to the c++ standard containers in STL, so are familiar with them. All containers are generic/templated, except for **cstr** and **cbits**. No casting is used, so containers are type-safe like templates in c++. A basic usage example: ```c -#define i_type FVec // Container type name; if not defined, it would be cvec_float +#define i_type Floats // Container type name; if not defined, it would be cvec_float #define i_val float // Container element type -#include <stc/cvec.h> +#include <stc/cvec.h> // "instantiate" the desired container type +#include <stdio.h> int main(void) { - FVec vec = FVec_init(); - FVec_push(&vec, 10.f); - FVec_push(&vec, 20.f); - FVec_push(&vec, 30.f); + Floats nums = Floats_init(); + Floats_push(&nums, 30.f); + Floats_push(&nums, 10.f); + Floats_push(&nums, 20.f); - for (intptr_t i = 0; i < FVec_size(vec); ++i) - printf(" %g", vec.data[i]); + for (int i = 0; i < Floats_size(&nums); ++i) + printf(" %g", nums.data[i]); + + Floats_sort(&nums); - FVec_drop(&vec); // cleanup memory + c_foreach (i, Floats, nums) // Alternative way to iterate nums. + printf(" %g", *i.ref); // i.ref is a pointer to the current element. + + Floats_drop(&nums); // cleanup memory } ``` -Below is an alternative way to write this with STC. It uses the generic flow control macros `c_auto` and `c_foreach`, and the function macro *c_make()*. This simplifies the code and makes it less prone to errors: +To switch to a different container type is easy when using `c_foreach`: ```c +#define i_type Floats +#define i_val float +#include <stc/csset.h> // Use a sorted set instead +#include <stdio.h> + int main() { - c_auto (FVec, vec) // RAII: define, init() and drop() combined. - { - vec = c_make(FVec, {10.f, 20.f, 30.f}); // Initialize with a list of floats. + Floats nums = c_make(Floats, {30.f, 10.f, 20.f}); // Initialize with a list of floats. + Floats_push(&nums, 50.f); + Floats_push(&nums, 40.f); - c_foreach (i, FVec, vec) // Iterate elements of the container. - printf(" %g", *i.ref); // i.ref is a pointer to the current element. - } - // vec is "dropped" at end of c_auto scope + // print the sorted numbers + c_foreach (i, Floats, nums) + printf(" %g", *i.ref); + + Floats_drop(&nums); } ``` -For user defined struct elements, `i_cmp` compare function should be defined, as the default `<` and `==` -only works for integral types. *Alternatively, `#define i_opt c_no_cmp` to disable sorting and searching*. - -Similarily, if an element destructor `i_valdrop` is defined, `i_valclone` function is required. +For user-defined struct elements, `i_cmp` compare function should be defined, as the default `<` and `==` +only works for integral types. *Alternatively, `#define i_opt c_no_cmp` to disable sorting and searching*. Similarily, if an element destructor `i_valdrop` is defined, `i_valclone` function is required. *Alternatively `#define i_opt c_no_clone` to disable container cloning.* -In order to include two **cvec**'s with different element types, include <stc/cvec.h> twice: +Let's make a vector of vectors that can be cloned. All of its element vectors will be destroyed when destroying the Vec2D. ```c -#define i_val struct One -#define i_opt c_no_cmp -#define i_tag one +#define i_type Vec +#define i_val float #include <stc/cvec.h> +#include <stdio.h> -#define i_val struct Two -#define i_opt c_no_cmp -#define i_tag two +#define i_type Vec2D +#define i_valclass Vec // Use i_valclass when element type has "member" functions Vec_clone(), Vec_drop() and Vec_cmp(). +#define i_opt c_no_cmp // Disable search/sort for Vec2D because Vec_cmp() is not defined. #include <stc/cvec.h> -... -cvec_one v1 = cvec_one_init(); -cvec_two v2 = cvec_two_init(); -``` -An example using six different container types: +int main(void) +{ + Vec* v; + Vec2D vec = {0}; // All containers in STC can be initialized with {0}. + v = Vec2D_push(&vec, Vec_init()); // Returns a pointer to the new element in vec. + Vec_push(v, 10.f); + Vec_push(v, 20.f); + + v = Vec2D_push(&vec, Vec_init()); + Vec_push(v, 30.f); + Vec_push(v, 40.f); + + Vec2D clone = Vec2D_clone(vec); // Make a deep-copy of vec + + c_foreach (i, Vec2D, clone) // Loop through the cloned vector + c_foreach (j, Vec, *i.ref) + printf(" %g", *j.ref); + + c_drop(Vec2D, &vec, &clone); // Cleanup all (6) vectors. +} +``` +Here is an example of using six different container types: ```c #include <stdio.h> #include <stc/ccommon.h> struct Point { float x, y; }; -int Point_cmp(const struct Point* a, const struct Point* b); #define i_key int #include <stc/cset.h> // cset_int: unordered set #define i_val struct Point -#define i_cmp Point_cmp +// Define a i_less template parameter (alternative to i_cmp) for Point. +#define i_less(a, b) a->x < b->x || (a->x == b->x && a->y < b->y) #define i_tag pnt -#include <stc/cvec.h> // cvec_pnt: vector of struct Point +#include <stc/cvec.h> // cvec_pnt: vector of struct Point #define i_val int -#include <stc/cdeq.h> // cdeq_int: deque of int +#include <stc/cdeq.h> // cdeq_int: deque of int #define i_val int -#include <stc/clist.h> // clist_int: singly linked list +#include <stc/clist.h> // clist_int: singly linked list #define i_val int -#include <stc/cstack.h> +#include <stc/cstack.h> // cstack_int #define i_key int #define i_val int -#include <stc/csmap.h> // csmap_int: sorted map int => int - -int Point_cmp(const struct Point* a, const struct Point* b) { - int cmp = c_default_cmp(&a->x, &b->x); - return cmp ? cmp : c_default_cmp(&a->y, &b->y); -} +#include <stc/csmap.h> // csmap_int: sorted map int => int int main(void) { - /* Define six containers with automatic call of init and drop (destruction after scope exit) */ - c_auto (cset_int, set) - c_auto (cvec_pnt, vec) - c_auto (cdeq_int, deq) - c_auto (clist_int, lst) - c_auto (cstack_int, stk) - c_auto (csmap_int, map) - { + // Define six empty containers + cset_int set = {0}; + cvec_pnt vec = {0}; + cdeq_int deq = {0}; + clist_int lst = {0}; + cstack_int stk = {0}; + csmap_int map = {0}; + + c_defer( // Drop the containers after the scope is executed + cset_int_drop(&set), + cvec_pnt_drop(&vec), + cdeq_int_drop(&deq), + clist_int_drop(&lst), + cstack_int_drop(&stk), + csmap_int_drop(&map) + ){ int nums[4] = {10, 20, 30, 40}; struct Point pts[4] = { {10, 1}, {20, 2}, {30, 3}, {40, 4} }; int pairs[4][2] = { {20, 2}, {10, 1}, {30, 3}, {40, 4} }; - /* Add some elements to each container */ + // Add some elements to each container for (int i = 0; i < 4; ++i) { cset_int_insert(&set, nums[i]); cvec_pnt_push(&vec, pts[i]); @@ -259,7 +289,7 @@ int main(void) csmap_int_insert(&map, pairs[i][0], pairs[i][1]); } - /* Find an element in each container (except cstack) */ + // Find an element in each container (except cstack) cset_int_iter i1 = cset_int_find(&set, 20); cvec_pnt_iter i2 = cvec_pnt_find(&vec, (struct Point){20, 2}); cdeq_int_iter i3 = cdeq_int_find(&deq, 20); @@ -270,7 +300,7 @@ int main(void) *i1.ref, i2.ref->x, i2.ref->y, *i3.ref, *i4.ref, i5.ref->first, i5.ref->second); - /* Erase the elements found */ + // Erase all the elements found cset_int_erase_at(&set, i1); cvec_pnt_erase_at(&vec, i2); cdeq_int_erase_at(&deq, i3); @@ -446,17 +476,19 @@ and non-emplace methods: #define i_val_str // special macro to enable container of cstr #include <stc/cvec.h> // vector of string (cstr) ... -c_auto (cvec_str, vec) // declare and call cvec_str_init() and defer cvec_str_drop(&vec) -c_with (cstr s = cstr_lit("a string literal"), cstr_drop(&s)) -{ - const char* hello = "Hello"; - cvec_str_push_back(&vec, cstr_from(hello); // construct and add string from const char* - cvec_str_push_back(&vec, cstr_clone(s)); // clone and append a cstr +cvec_str vec = {0}; +cstr s = cstr_lit("a string literal"); +const char* hello = "Hello"; - cvec_str_emplace_back(&vec, "Yay, literal"); // internally constructs cstr from const char* - cvec_str_emplace_back(&vec, cstr_clone(s)); // <-- COMPILE ERROR: expects const char* - cvec_str_emplace_back(&vec, cstr_str(&s)); // Ok: const char* input type. -} +cvec_str_push_back(&vec, cstr_from(hello); // construct and add string from const char* +cvec_str_push_back(&vec, cstr_clone(s)); // clone and append a cstr + +cvec_str_emplace_back(&vec, "Yay, literal"); // internally constructs cstr from const char* +cvec_str_emplace_back(&vec, cstr_clone(s)); // <-- COMPILE ERROR: expects const char* +cvec_str_emplace_back(&vec, cstr_str(&s)); // Ok: const char* input type. + +cstr_drop(&s) +cvec_str_drop(&vec); ``` This is made possible because the type configuration may be given an optional conversion/"rawvalue"-type as template parameter, along with a back and forth conversion @@ -552,9 +584,6 @@ STC is generally very memory efficient. Type sizes: - New + renamed loop iteration/scope macros: - `c_forlist`: macro replacing `c_forarray` and `c_apply`. Iterate a compound literal list. - `c_forrange`: macro replacing `c_forrange`. Iterate a `long long` type number sequence. - - `c_with`: macro renamed from `c_autovar`. Like Python's **with** statement. - - `c_scope`: macro renamed from `c_autoscope`. - - `c_defer`: macro renamed from `c_autodefer`. Resembles Go's and Zig's **defer**. - Updated **cstr**, now always takes self as pointer, like all containers except csview. - Updated **cvec**, **cdeq**, changed `*_range*` function names. diff --git a/docs/carc_api.md b/docs/carc_api.md index cc6c9c32..48b64ff0 100644 --- a/docs/carc_api.md +++ b/docs/carc_api.md @@ -98,56 +98,56 @@ bool carc_X_value_eq(const i_val* x, const i_val* y); int main() { - c_auto (Stack, s1, s2) // RAII - { - // POPULATE s1 with shared pointers to Map: - Map *map; - - map = Stack_push(&s1, Arc_make(Map_init()))->get; // push empty map to s1. - c_forlist (i, Map_raw, { {"Joey", 1990}, {"Mary", 1995}, {"Joanna", 1992} }) { - Map_emplace(map, c_PAIR(i.ref)); // populate it. - } - - map = Stack_push(&s1, Arc_make(Map_init()))->get; - c_forlist (i, Map_raw, { {"Rosanna", 2001}, {"Brad", 1999}, {"Jack", 1980} }) { - Map_emplace(map, c_PAIR(i.ref)); - } - - // POPULATE s2: - map = Stack_push(&s2, Arc_make(Map_init()))->get; - c_forlist (i, Map_raw, { {"Steve", 1979}, {"Rick", 1974}, {"Tracy", 2003} }) { - Map_emplace(map, c_PAIR(i.ref)); - } - - // Share two Maps from s1 with s2 by cloning(=sharing) the carcs: - Stack_push(&s2, Arc_clone(s1.data[0])); - Stack_push(&s2, Arc_clone(s1.data[1])); - - // Deep-copy (does not share) a Map from s1 to s2. - // s2 will contain two shared and two unshared maps. - map = Stack_push(&s2, Arc_from(Map_clone(*s1.data[1].get)))->get; - - // Add one more element to the cloned map: - Map_emplace_or_assign(map, "Cloned", 2022); - - // Add one more element to the shared map: - Map_emplace_or_assign(s1.data[1].get, "Shared", 2022); - - puts("S1"); - c_foreach (i, Stack, s1) { - c_forpair (name, year, Map, *i.ref->get) - printf(" %s:%d", cstr_str(_.name), *_.year); - puts(""); - } - - puts("S2"); - c_foreach (i, Stack, s2) { - c_forpair (name, year, Map, *i.ref->get) - printf(" %s:%d", cstr_str(_.name), *_.year); - puts(""); - } + Stack s1 = {0}, s2 = {0}; + Map *map; + + // POPULATE s1 with shared pointers to Map: + map = Stack_push(&s1, Arc_make(Map_init()))->get; // push empty map to s1. + Map_emplace(map, "Joey", 1990); + Map_emplace(map, "Mary", 1995); + Map_emplace(map, "Joanna", 1992); + + map = Stack_push(&s1, Arc_make(Map_init()))->get; + Map_emplace(map, "Rosanna", 2001); + Map_emplace(map, "Brad", 1999); + Map_emplace(map, "Jack", 1980); + + // POPULATE s2: + map = Stack_push(&s2, Arc_make(Map_init()))->get; + Map_emplace(map, "Steve", 1979); + Map_emplace(map, "Rick", 1974); + Map_emplace(map, "Tracy", 2003); + + // Share two Maps from s1 with s2 by cloning(=sharing) the carcs: + Stack_push(&s2, Arc_clone(s1.data[0])); + Stack_push(&s2, Arc_clone(s1.data[1])); + + // Deep-copy (does not share) a Map from s1 to s2. + // s2 will contain two shared and two unshared maps. + map = Stack_push(&s2, Arc_from(Map_clone(*s1.data[1].get)))->get; + + // Add one more element to the cloned map: + Map_emplace_or_assign(map, "Cloned", 2022); + + // Add one more element to the shared map: + Map_emplace_or_assign(s1.data[1].get, "Shared", 2022); + + puts("S1"); + c_foreach (i, Stack, s1) { + c_forpair (name, year, Map, *i.ref->get) + printf(" %s:%d", cstr_str(_.name), *_.year); puts(""); } + + puts("S2"); + c_foreach (i, Stack, s2) { + c_forpair (name, year, Map, *i.ref->get) + printf(" %s:%d", cstr_str(_.name), *_.year); + puts(""); + } + puts(""); + + c_drop(Stack, &s1, &s2); } ``` Output: diff --git a/docs/cbox_api.md b/docs/cbox_api.md index 8b03d004..ca4d90da 100644 --- a/docs/cbox_api.md +++ b/docs/cbox_api.md @@ -92,11 +92,12 @@ void int_drop(int* x) { int main() { - c_auto (IVec, vec) // declare and init vec, call drop at scope exit - c_auto (ISet, set) // similar - { - vec = c_make(Vec, {2021, 2012, 2022, 2015}); - + IVec vec = c_make(Vec, {2021, 2012, 2022, 2015}); + ISet set = {0}; + c_defer( + IVec_drop(&vec), + ISet_drop(&set) + ){ printf("vec:"); c_foreach (i, IVec, vec) printf(" %d", *i.ref->get); diff --git a/docs/ccommon_api.md b/docs/ccommon_api.md index 64daad42..010ea204 100644 --- a/docs/ccommon_api.md +++ b/docs/ccommon_api.md @@ -2,96 +2,6 @@ The following macros are recommended to use, and they safe/have no side-effects. -## Scope macros (RAII) -### c_auto, c_with, c_scope, c_defer -General ***defer*** mechanics for resource acquisition. These macros allows you to specify the -freeing of the resources at the point where the acquisition takes place. -The **checkauto** utility described below, ensures that the `c_auto*` macros are used correctly. - -| Usage | Description | -|:---------------------------------------|:----------------------------------------------------------| -| `c_with (Type var=init, drop)` | Declare `var`. Defer `drop...` to end of scope | -| `c_with (Type var=init, pred, drop)` | Adds a predicate in order to exit early if init failed | -| `c_auto (Type, var1,...,var4)` | `c_with (Type var1=Type_init(), Type_drop(&var1))` ... | -| `c_scope (init, drop)` | Execute `init` and defer `drop` to end of scope | -| `c_defer (drop...)` | Defer `drop...` to end of scope | -| `continue` | Exit a block above without memory leaks | - -For multiple variables, use either multiple **c_with** in sequence, or declare variable outside -scope and use **c_scope**. For convenience, **c_auto** support up to 4 variables. -```c -// `c_with` is similar to python `with`: it declares and can drop a variable after going out of scope. -bool ok = false; -c_with (uint8_t* buf = malloc(BUF_SIZE), buf != NULL, free(buf)) -c_with (FILE* fp = fopen(fname, "rb"), fp != NULL, fclose(fp)) -{ - int n = fread(buf, 1, BUF_SIZE, fp); - if (n <= 0) continue; // auto cleanup! NB do not break or return here. - ... - ok = true; -} -return ok; - -// `c_auto` automatically initialize and destruct up to 4 variables: -c_auto (cstr, s1, s2) -{ - cstr_append(&s1, "Hello"); - cstr_append(&s1, " world"); - - cstr_append(&s2, "Cool"); - cstr_append(&s2, " stuff"); - - printf("%s %s\n", cstr_str(&s1), cstr_str(&s2)); -} - -// `c_with` is a general variant of `c_auto`: -c_with (cstr str = cstr_lit("Hello"), cstr_drop(&str)) -{ - cstr_append(&str, " world"); - printf("%s\n", cstr_str(&str)); -} - -// `c_scope` is like `c_with` but works with an already declared variable. -static pthread_mutex_t mut; -c_scope (pthread_mutex_lock(&mut), pthread_mutex_unlock(&mut)) -{ - /* Do syncronized work. */ -} - -// `c_defer` executes the expressions when leaving scope. Prefer c_with or c_scope. -cstr s1 = cstr_lit("Hello"), s2 = cstr_lit("world"); -c_defer (cstr_drop(&s1), cstr_drop(&s2)) -{ - printf("%s %s\n", cstr_str(&s1), cstr_str(&s2)); -} -``` -**Example**: Load each line of a text file into a vector of strings: -```c -#include <errno.h> -#include <stc/cstr.h> - -#define i_val_str -#include <stc/cvec.h> - -// receiver should check errno variable -cvec_str readFile(const char* name) -{ - cvec_str vec = cvec_str_init(); // returned - - c_with (FILE* fp = fopen(name, "r"), fp != NULL, fclose(fp)) - c_with (cstr line = cstr_NULL, cstr_drop(&line)) - while (cstr_getline(&line, fp)) - cvec_str_emplace_back(&vec, cstr_str(&line)); - return vec; -} - -int main() -{ - c_with (cvec_str x = readFile(__FILE__), cvec_str_drop(&x)) - c_foreach (i, cvec_str, x) - printf("%s\n", cstr_str(i.ref)); -} -``` ## Loop abstraction macros ### c_foreach, c_foreach_r, c_forpair @@ -165,10 +75,6 @@ c_forlist (i, cmap_ii_raw, { {4, 5}, {6, 7} }) // string literals pushed to a stack of cstr: c_forlist (i, const char*, {"Hello", "crazy", "world"}) cstack_str_emplace(&stk, *i.ref); - -// reverse the list: -c_forlist (i, int, {1, 2, 3}) - cvec_i_push_back(&vec, i.data[i.size - 1 - i.index]); ``` ### c_forfilter @@ -297,13 +203,18 @@ if (it.ref) cmap_str_erase_at(&map, it); c_erase_if(i, csmap_str, map, cstr_contains(i.ref, "hello")); ``` -### c_swap, c_drop +### c_swap, c_drop, c_const_cast ```c // Safe macro for swapping internals of two objects of same type: c_swap(cmap_int, &map1, &map2); // Drop multiple containers of same type: c_drop(cvec_i, &vec1, &vec2, &vec3); + +// Type-safe casting a from const (pointer): +const char* cs = "Hello"; +char* s = c_const_cast(char*, cs); // OK +int* ip = c_const_cast(int*, cs); // issues a warning! ``` ### General predefined template parameter functions @@ -329,7 +240,99 @@ int array[] = {1, 2, 3, 4}; intptr_t n = c_arraylen(array); ``` -## The **checkauto** utility program (for RAII) +## Scope macros (RAII) +### c_auto, c_with, c_scope, c_defer +General ***defer*** mechanics for resource acquisition. These macros allows you to specify the +freeing of the resources at the point where the acquisition takes place. +The **checkauto** utility described below, ensures that the `c_auto*` macros are used correctly. + +| Usage | Description | +|:---------------------------------------|:----------------------------------------------------------| +| `c_defer (drop...)` | Defer `drop...` to end of scope | +| `c_scope (init, drop)` | Execute `init` and defer `drop` to end of scope | +| `c_scope (init, pred, drop)` | Adds a predicate in order to exit early if init failed | +| `c_with (Type var=init, drop)` | Declare `var`. Defer `drop...` to end of scope | +| `c_with (Type var=init, pred, drop)` | Adds a predicate in order to exit early if init failed | +| `c_auto (Type, var1,...,var4)` | `c_with (Type var1=Type_init(), Type_drop(&var1))` ... | +| `continue` | Exit a block above without memory leaks | + +For multiple variables, use either multiple **c_with** in sequence, or declare variable outside +scope and use **c_scope**. For convenience, **c_auto** support up to 4 variables. +```c +// `c_with` is similar to python `with`: it declares and can drop a variable after going out of scope. +bool ok = false; +c_with (uint8_t* buf = malloc(BUF_SIZE), buf != NULL, free(buf)) +c_with (FILE* fp = fopen(fname, "rb"), fp != NULL, fclose(fp)) +{ + int n = fread(buf, 1, BUF_SIZE, fp); + if (n <= 0) continue; // auto cleanup! NB do not break or return here. + ... + ok = true; +} +return ok; + +// `c_auto` automatically initialize and destruct up to 4 variables: +c_auto (cstr, s1, s2) +{ + cstr_append(&s1, "Hello"); + cstr_append(&s1, " world"); + + cstr_append(&s2, "Cool"); + cstr_append(&s2, " stuff"); + + printf("%s %s\n", cstr_str(&s1), cstr_str(&s2)); +} + +// `c_with` is a general variant of `c_auto`: +c_with (cstr str = cstr_lit("Hello"), cstr_drop(&str)) +{ + cstr_append(&str, " world"); + printf("%s\n", cstr_str(&str)); +} + +// `c_scope` is like `c_with` but works with an already declared variable. +static pthread_mutex_t mut; +c_scope (pthread_mutex_lock(&mut), pthread_mutex_unlock(&mut)) +{ + /* Do syncronized work. */ +} + +// `c_defer` executes the expressions when leaving scope. Prefer c_with or c_scope. +cstr s1 = cstr_lit("Hello"), s2 = cstr_lit("world"); +c_defer (cstr_drop(&s1), cstr_drop(&s2)) +{ + printf("%s %s\n", cstr_str(&s1), cstr_str(&s2)); +} +``` +**Example**: Load each line of a text file into a vector of strings: +```c +#include <errno.h> +#include <stc/cstr.h> + +#define i_val_str +#include <stc/cvec.h> + +// receiver should check errno variable +cvec_str readFile(const char* name) +{ + cvec_str vec = cvec_str_init(); // returned + + c_with (FILE* fp = fopen(name, "r"), fp != NULL, fclose(fp)) + c_with (cstr line = cstr_NULL, cstr_drop(&line)) + while (cstr_getline(&line, fp)) + cvec_str_emplace_back(&vec, cstr_str(&line)); + return vec; +} + +int main() +{ + c_with (cvec_str x = readFile(__FILE__), cvec_str_drop(&x)) + c_foreach (i, cvec_str, x) + printf("%s\n", cstr_str(i.ref)); +} +``` + +### The **checkauto** utility program (for RAII) The **checkauto** program will check the source code for any misuses of the `c_auto*` macros which may lead to resource leakages. The `c_auto*`- macros are implemented as one-time executed **for-loops**, so any `return` or `break` appearing within such a block will lead to resource leaks, as it will disable diff --git a/docs/clist_api.md b/docs/clist_api.md index be6949ec..a1dbe105 100644 --- a/docs/clist_api.md +++ b/docs/clist_api.md @@ -193,21 +193,20 @@ Splice `[30, 40]` from *L2* into *L1* before `3`: #include <stdio.h> int main() { - c_auto (clist_i, L1, L2) - { - L1 = c_make(clist_i, {1, 2, 3, 4, 5}); - L2 = c_make(clist_i, {10, 20, 30, 40, 50}); + clist_i L1 = c_make(clist_i, {1, 2, 3, 4, 5}); + clist_i L2 = c_make(clist_i, {10, 20, 30, 40, 50}); - clist_i_iter i = clist_i_advance(clist_i_begin(&L1), 2); - clist_i_iter j1 = clist_i_advance(clist_i_begin(&L2), 2), j2 = clist_i_advance(j1, 2); + clist_i_iter i = clist_i_advance(clist_i_begin(&L1), 2); + clist_i_iter j1 = clist_i_advance(clist_i_begin(&L2), 2), j2 = clist_i_advance(j1, 2); - clist_i_splice_range(&L1, i, &L2, j1, j2); + clist_i_splice_range(&L1, i, &L2, j1, j2); - c_foreach (i, clist_i, L1) - printf(" %d", *i.ref); puts(""); - c_foreach (i, clist_i, L2) - printf(" %d", *i.ref); puts(""); - } + c_foreach (i, clist_i, L1) + printf(" %d", *i.ref); puts(""); + c_foreach (i, clist_i, L2) + printf(" %d", *i.ref); puts(""); + + c_drop(clist_i, &L1, &L2); } ``` Output: diff --git a/docs/cmap_api.md b/docs/cmap_api.md index bf3dddcc..71e00265 100644 --- a/docs/cmap_api.md +++ b/docs/cmap_api.md @@ -125,27 +125,26 @@ bool c_memcmp_eq(const i_keyraw* a, const i_keyraw* b); // ! int main() { // Create an unordered_map of three strings (that map to strings) - c_auto (cmap_str, u) - { - u = c_make(cmap_str, { - {"RED", "#FF0000"}, - {"GREEN", "#00FF00"}, - {"BLUE", "#0000FF"} - }); - - // Iterate and print keys and values of unordered map - c_foreach (n, cmap_str, u) { - printf("Key:[%s] Value:[%s]\n", cstr_str(&n.ref->first), cstr_str(&n.ref->second)); - } - - // Add two new entries to the unordered map - cmap_str_emplace(&u, "BLACK", "#000000"); - cmap_str_emplace(&u, "WHITE", "#FFFFFF"); - - // Output values by key - printf("The HEX of color RED is:[%s]\n", cstr_str(cmap_str_at(&u, "RED"))); - printf("The HEX of color BLACK is:[%s]\n", cstr_str(cmap_str_at(&u, "BLACK"))); + cmap_str umap = c_make(cmap_str, { + {"RED", "#FF0000"}, + {"GREEN", "#00FF00"}, + {"BLUE", "#0000FF"} + }); + + // Iterate and print keys and values of unordered map + c_foreach (n, cmap_str, umap) { + printf("Key:[%s] Value:[%s]\n", cstr_str(&n.ref->first), cstr_str(&n.ref->second)); } + + // Add two new entries to the unordered map + cmap_str_emplace(&umap, "BLACK", "#000000"); + cmap_str_emplace(&umap, "WHITE", "#FFFFFF"); + + // Output values by key + printf("The HEX of color RED is:[%s]\n", cstr_str(cmap_str_at(&umap, "RED"))); + printf("The HEX of color BLACK is:[%s]\n", cstr_str(cmap_str_at(&umap, "BLACK"))); + + cmap_str_drop(&umap); } ``` Output: @@ -161,33 +160,33 @@ The HEX of color BLACK is:[#000000] This example uses a cmap with cstr as mapped value. ```c #include <stc/cstr.h> - +#define i_type IDMap #define i_key int #define i_val_str -#define i_tag id #include <stc/cmap.h> int main() { uint32_t col = 0xcc7744ff; - c_auto (cmap_id, idnames) - { - c_forlist (i, cmap_id_raw, { {100, "Red"}, {110, "Blue"} }) - cmap_id_emplace(&idnames, c_PAIR(i.ref)); - - // replace existing mapped value: - cmap_id_emplace_or_assign(&idnames, 110, "White"); - - // insert a new constructed mapped string into map: - cmap_id_insert_or_assign(&idnames, 120, cstr_from_fmt("#%08x", col)); - - // emplace/insert does nothing if key already exist: - cmap_id_emplace(&idnames, 100, "Green"); - - c_foreach (i, cmap_id, idnames) - printf("%d: %s\n", i.ref->first, cstr_str(&i.ref->second)); - } + IDMap idnames = {0}; + + c_forlist (i, IDMap_raw, { {100, "Red"}, {110, "Blue"} }) + IDMap_emplace(&idnames, i.ref->first, i.ref->second); + + // replace existing mapped value: + IDMap_emplace_or_assign(&idnames, 110, "White"); + + // insert a new constructed mapped string into map: + IDMap_insert_or_assign(&idnames, 120, cstr_from_fmt("#%08x", col)); + + // emplace/insert does nothing if key already exist: + IDMap_emplace(&idnames, 100, "Green"); + + c_foreach (i, IDMap, idnames) + printf("%d: %s\n", i.ref->first, cstr_str(&i.ref->second)); + + IDMap_drop(&idnames); } ``` Output: @@ -212,16 +211,17 @@ typedef struct { int x, y, z; } Vec3i; int main() { // Define map with defered destruct - c_with (cmap_vi vecs = cmap_vi_init(), cmap_vi_drop(&vecs)) - { - cmap_vi_insert(&vecs, (Vec3i){100, 0, 0}, 1); - cmap_vi_insert(&vecs, (Vec3i){ 0, 100, 0}, 2); - cmap_vi_insert(&vecs, (Vec3i){ 0, 0, 100}, 3); - cmap_vi_insert(&vecs, (Vec3i){100, 100, 100}, 4); - - c_forpair (v3, num, cmap_vi, vecs) - printf("{ %3d, %3d, %3d }: %d\n", _.v3->x, _.v3->y, _.v3->z, *_.num); - } + cmap_vi vecs = {0}; + + cmap_vi_insert(&vecs, (Vec3i){100, 0, 0}, 1); + cmap_vi_insert(&vecs, (Vec3i){ 0, 100, 0}, 2); + cmap_vi_insert(&vecs, (Vec3i){ 0, 0, 100}, 3); + cmap_vi_insert(&vecs, (Vec3i){100, 100, 100}, 4); + + c_forpair (v3, num, cmap_vi, vecs) + printf("{ %3d, %3d, %3d }: %d\n", _.v3->x, _.v3->y, _.v3->z, *_.num); + + cmap_vi_drop(&vecs); } ``` Output: @@ -245,16 +245,17 @@ typedef struct { int x, y, z; } Vec3i; int main() { - c_auto (cmap_iv, vecs) // shorthand for c_with with _init(), _drop(). - { - cmap_iv_insert(&vecs, 1, (Vec3i){100, 0, 0}); - cmap_iv_insert(&vecs, 2, (Vec3i){ 0, 100, 0}); - cmap_iv_insert(&vecs, 3, (Vec3i){ 0, 0, 100}); - cmap_iv_insert(&vecs, 4, (Vec3i){100, 100, 100}); - - c_forpair (num, v3, cmap_iv, vecs) - printf("%d: { %3d, %3d, %3d }\n", *_.num, _.v3->x, _.v3->y, _.v3->z); - } + cmap_iv vecs = {0} + + cmap_iv_insert(&vecs, 1, (Vec3i){100, 0, 0}); + cmap_iv_insert(&vecs, 2, (Vec3i){ 0, 100, 0}); + cmap_iv_insert(&vecs, 3, (Vec3i){ 0, 0, 100}); + cmap_iv_insert(&vecs, 4, (Vec3i){100, 100, 100}); + + c_forpair (num, v3, cmap_iv, vecs) + printf("%d: { %3d, %3d, %3d }\n", *_.num, _.v3->x, _.v3->y, _.v3->z); + + cmap_iv_drop(&vecs); } ``` Output: @@ -300,35 +301,27 @@ static inline void Viking_drop(Viking* vk) { #define i_type Vikings #define i_keyclass Viking #define i_val int -/* - i_keyclass implies these defines, unless they are already defined: - #define i_cmp Viking_cmp - #define i_hash Viking_hash - #define i_keyclone Viking_clone - #define i_keydrop Viking_drop -*/ #include <stc/cmap.h> int main() { // Use a HashMap to store the vikings' health points. - c_auto (Vikings, vikings) // uses Vikings_init(), Vikings_drop() - { - Vikings_insert(&vikings, (Viking){cstr_lit("Einar"), cstr_lit("Norway")}, 25); - Vikings_insert(&vikings, (Viking){cstr_lit("Olaf"), cstr_lit("Denmark")}, 24); - Vikings_insert(&vikings, (Viking){cstr_lit("Harald"), cstr_lit("Iceland")}, 12); - Vikings_insert(&vikings, (Viking){cstr_lit("Einar"), cstr_lit("Denmark")}, 21); - - c_auto (Viking, lookup) { - lookup = (Viking){cstr_lit("Einar"), cstr_lit("Norway")}; - printf("Lookup: Einar of Norway has %d hp\n\n", *Vikings_at(&vikings, lookup)); - } - - // Print the status of the vikings. - c_forpair (vik, hp, Vikings, vikings) { - printf("%s of %s has %d hp\n", cstr_str(&_.vik->name), cstr_str(&_.vik->country), *_.hp); - } + Vikings vikings = {0}; + + Vikings_insert(&vikings, (Viking){cstr_lit("Einar"), cstr_lit("Norway")}, 25); + Vikings_insert(&vikings, (Viking){cstr_lit("Olaf"), cstr_lit("Denmark")}, 24); + Vikings_insert(&vikings, (Viking){cstr_lit("Harald"), cstr_lit("Iceland")}, 12); + Vikings_insert(&vikings, (Viking){cstr_lit("Einar"), cstr_lit("Denmark")}, 21); + + Viking lookup = (Viking){cstr_lit("Einar"), cstr_lit("Norway")}; + printf("Lookup: Einar of Norway has %d hp\n\n", *Vikings_at(&vikings, lookup)); + Viking_drop(&lookup); + + // Print the status of the vikings. + c_forpair (vik, hp, Vikings, vikings) { + printf("%s of %s has %d hp\n", cstr_str(&_.vik->name), cstr_str(&_.vik->country), *_.hp); } + Vikings_drop(&vikings); } ``` Output: @@ -384,30 +377,22 @@ static inline RViking Viking_toraw(const Viking* vp) { #define i_hash(rp) (cstrhash(rp->name) ^ cstrhash(rp->country)) #define i_val int #include <stc/cmap.h> -/* - i_keyclass implies these defines, unless they are already defined: - #define i_cmp RViking_cmp - //#define i_hash RViking_hash // already defined above. - //#define i_keyclone Viking_clone // not used because c_no_clone - #define i_keyto Viking_toraw // because i_keyraw type is defined - #define i_keydrop Viking_drop -*/ int main() { - c_auto (Vikings, vikings) - { - Vikings_emplace(&vikings, (RViking){"Einar", "Norway"}, 20); - Vikings_emplace(&vikings, (RViking){"Olaf", "Denmark"}, 24); - Vikings_emplace(&vikings, (RViking){"Harald", "Iceland"}, 12); - Vikings_emplace(&vikings, (RViking){"Björn", "Sweden"}, 10); - - Vikings_value *v = Vikings_get_mut(&vikings, (RViking){"Einar", "Norway"}); - if (v) 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 vikings = {0}; + + Vikings_emplace(&vikings, (RViking){"Einar", "Norway"}, 20); + Vikings_emplace(&vikings, (RViking){"Olaf", "Denmark"}, 24); + Vikings_emplace(&vikings, (RViking){"Harald", "Iceland"}, 12); + Vikings_emplace(&vikings, (RViking){"Björn", "Sweden"}, 10); + + Vikings_value *v = Vikings_get_mut(&vikings, (RViking){"Einar", "Norway"}); + if (v) 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/docs/coption_api.md b/docs/coption_api.md index be0d0978..1e85ac2a 100644 --- a/docs/coption_api.md +++ b/docs/coption_api.md @@ -66,6 +66,4 @@ int main(int argc, char *argv[]) { printf(" %s", argv[i]); putchar('\n'); } - return 0; -} ``` diff --git a/docs/cpque_api.md b/docs/cpque_api.md index 991623d7..b3a1a9ec 100644 --- a/docs/cpque_api.md +++ b/docs/cpque_api.md @@ -75,24 +75,24 @@ int main() stc64_t rng = stc64_new(1234); stc64_uniform_t dist = stc64_uniform_new(0, N * 10); - // Declare heap, with defered drop() - c_auto (cpque_i, heap) - { - // Push ten million random numbers to priority queue. - c_forrange (N) - cpque_i_push(&heap, stc64_uniform(&rng, &dist)); - - // Add some negative ones. - int nums[] = {-231, -32, -873, -4, -343}; - c_forrange (i, c_ARRAYLEN(nums)) - cpque_i_push(&heap, nums[i]); - - // Extract and display the fifty smallest. - c_forrange (50) { - printf("%" PRId64 " ", *cpque_i_top(&heap)); - cpque_i_pop(&heap); - } + // Define heap + cpque_i heap = {0}; + + // Push ten million random numbers to priority queue. + c_forrange (N) + cpque_i_push(&heap, stc64_uniform(&rng, &dist)); + + // Add some negative ones. + int nums[] = {-231, -32, -873, -4, -343}; + c_forrange (i, c_ARRAYLEN(nums)) + cpque_i_push(&heap, nums[i]); + + // Extract and display the fifty smallest. + c_forrange (50) { + printf("%" PRId64 " ", *cpque_i_top(&heap)); + cpque_i_pop(&heap); } + cpque_i_drop(&heap); } ``` Output: diff --git a/docs/cset_api.md b/docs/cset_api.md index 287f7636..a0af357f 100644 --- a/docs/cset_api.md +++ b/docs/cset_api.md @@ -80,37 +80,35 @@ cset_X_value cset_X_value_clone(cset_X_value val); ## Example ```c #include <stc/cstr.h> - +#define i_type Strset #define i_key_str #include <stc/cset.h> int main () { - c_auto (cset_str, fifth) - { - c_auto (cset_str, first, second) - c_auto (cset_str, third, fourth) - { - second = c_make(cset_str, {"red", "green", "blue"}); - - c_forlist (i, const char*, {"orange", "pink", "yellow"}) - cset_str_emplace(&third, *i.ref); - - cset_str_emplace(&fourth, "potatoes"); - cset_str_emplace(&fourth, "milk"); - cset_str_emplace(&fourth, "flour"); - - fifth = cset_str_clone(second); - c_foreach (i, cset_str, third) - cset_str_emplace(&fifth, cstr_str(i.ref)); - - c_foreach (i, cset_str, fourth) - cset_str_emplace(&fifth, cstr_str(i.ref)); - } - printf("fifth contains:\n\n"); - c_foreach (i, cset_str, fifth) - printf("%s\n", cstr_str(i.ref)); - } + Strset first, second={0}, third={0}, fourth={0}, fifth; + + first = c_make(Strset, {"red", "green", "blue"}); + fifth = Strset_clone(second); + + c_forlist (i, const char*, {"orange", "pink", "yellow"}) + Strset_emplace(&third, *i.ref); + + c_foreach (i, Strset, third) + Strset_insert(&fifth, cstr_clone(*i.ref)); + + Strset_emplace(&fourth, "potatoes"); + Strset_emplace(&fourth, "milk"); + Strset_emplace(&fourth, "flour"); + + c_foreach (i, Strset, fourth) + Strset_emplace(&fifth, cstr_str(i.ref)); + + printf("fifth contains:\n\n"); + c_foreach (i, Strset, fifth) + printf("%s\n", cstr_str(i.ref)); + + c_drop(Strset, &first, &second, &third, &fourth, &fifth); } ``` Output: diff --git a/docs/csmap_api.md b/docs/csmap_api.md index 8e5780e3..da0e6915 100644 --- a/docs/csmap_api.md +++ b/docs/csmap_api.md @@ -112,27 +112,26 @@ csmap_X_raw csmap_X_value_toraw(csmap_X_value* pval); int main() { // Create a sorted map of three strings (maps to string) - c_auto (csmap_str, colors) // RAII - { - colors = c_make(csmap_str, { - {"RED", "#FF0000"}, - {"GREEN", "#00FF00"}, - {"BLUE", "#0000FF"} - }); - - // Iterate and print keys and values of sorted map - c_foreach (i, csmap_str, colors) { - printf("Key:[%s] Value:[%s]\n", cstr_str(&i.ref->first), cstr_str(&i.ref->second)); - } - - // Add two new entries to the sorted map - csmap_str_emplace(&colors, "BLACK", "#000000"); - csmap_str_emplace(&colors, "WHITE", "#FFFFFF"); - - // Output values by key - printf("The HEX of color RED is:[%s]\n", cstr_str(csmap_str_at(&colors, "RED"))); - printf("The HEX of color BLACK is:[%s]\n", cstr_str(csmap_str_at(&colors, "BLACK"))); + csmap_str colors = c_make(csmap_str, { + {"RED", "#FF0000"}, + {"GREEN", "#00FF00"}, + {"BLUE", "#0000FF"} + }); + + // Iterate and print keys and values of sorted map + c_foreach (i, csmap_str, colors) { + printf("Key:[%s] Value:[%s]\n", cstr_str(&i.ref->first), cstr_str(&i.ref->second)); } + + // Add two new entries to the sorted map + csmap_str_emplace(&colors, "BLACK", "#000000"); + csmap_str_emplace(&colors, "WHITE", "#FFFFFF"); + + // Output values by key + printf("The HEX of color RED is:[%s]\n", cstr_str(csmap_str_at(&colors, "RED"))); + printf("The HEX of color BLACK is:[%s]\n", cstr_str(csmap_str_at(&colors, "BLACK"))); + + csmap_str_drop(&colors); } ``` Output: @@ -149,32 +148,29 @@ This example uses a csmap with cstr as mapped value. ```c #include <stc/cstr.h> +#define i_type IDSMap #define i_key int #define i_val_str -#define i_tag id #include <stc/csmap.h> int main() { uint32_t col = 0xcc7744ff; - csmap_id idnames = csmap_id_init(); - c_defer (csmap_id_drop(&idnames)) - { - c_forlist (i, csmap_id_raw, { {100, "Red"}, {110, "Blue"} }) - csmap_id_emplace(&idnames, c_PAIR(i.ref)); + IDSMap idnames = c_make(IDSMap, { {100, "Red"}, {110, "Blue"} }); - // put replaces existing mapped value: - csmap_id_emplace_or_assign(&idnames, 110, "White"); + // Assign/overwrite an existing mapped value with a const char* + IDSMap_emplace_or_assign(&idnames, 110, "White"); - // put a constructed mapped value into map: - csmap_id_insert_or_assign(&idnames, 120, cstr_from_fmt("#%08x", col)); + // Insert (or assign) a new cstr + IDSMap_insert_or_assign(&idnames, 120, cstr_from_fmt("#%08x", col)); - // emplace adds only when key does not exist: - csmap_id_emplace(&idnames, 100, "Green"); + // emplace() adds only when key does not already exist: + IDSMap_emplace(&idnames, 100, "Green"); // ignored - c_foreach (i, csmap_id, idnames) - printf("%d: %s\n", i.ref->first, cstr_str(&i.ref->second)); - } + c_foreach (i, IDSMap, idnames) + printf("%d: %s\n", i.ref->first, cstr_str(&i.ref->second)); + + IDSMap_drop(&idnames); } ``` Output: @@ -205,16 +201,17 @@ static int Vec3i_cmp(const Vec3i* a, const Vec3i* b) { int main() { - c_auto (csmap_vi, vecs) - { - csmap_vi_insert(&vecs, (Vec3i){100, 0, 0}, 1); - csmap_vi_insert(&vecs, (Vec3i){0, 100, 0}, 2); - csmap_vi_insert(&vecs, (Vec3i){0, 0, 100}, 3); - csmap_vi_insert(&vecs, (Vec3i){100, 100, 100}, 4); - - c_foreach (i, csmap_vi, vecs) - printf("{ %3d, %3d, %3d }: %d\n", i.ref->first.x, i.ref->first.y, i.ref->first.z, i.ref->second); - } + csmap_vi vmap = {0}; + + csmap_vi_insert(&vmap, (Vec3i){100, 0, 0}, 1); + csmap_vi_insert(&vmap, (Vec3i){0, 100, 0}, 2); + csmap_vi_insert(&vmap, (Vec3i){0, 0, 100}, 3); + csmap_vi_insert(&vmap, (Vec3i){100, 100, 100}, 4); + + c_forpair (v, n, csmap_vi, vmap) + printf("{ %3d, %3d, %3d }: %d\n", _.v->x, _.v->y, _.v->z, *_.n); + + csmap_vi_drop(&vmap) } ``` Output: @@ -238,17 +235,17 @@ typedef struct { int x, y, z; } Vec3i; int main() { - // equivalent to: c_auto (csmap_iv, vecs) - c_with (csmap_iv vecs = csmap_iv_init(), csmap_iv_drop(&vecs)) - { - csmap_iv_insert(&vecs, 1, (Vec3i){100, 0, 0}); - csmap_iv_insert(&vecs, 2, (Vec3i){0, 100, 0}); - csmap_iv_insert(&vecs, 3, (Vec3i){0, 0, 100}); - csmap_iv_insert(&vecs, 4, (Vec3i){100, 100, 100}); - - c_foreach (i, csmap_iv, vecs) - printf("%d: { %3d, %3d, %3d }\n", i.ref->first, i.ref->second.x, i.ref->second.y, i.ref->second.z); - } + csmap_iv imap = {0}; + + csmap_iv_insert(&imap, 1, (Vec3i){100, 0, 0}); + csmap_iv_insert(&imap, 2, (Vec3i){0, 100, 0}); + csmap_iv_insert(&imap, 3, (Vec3i){0, 0, 100}); + csmap_iv_insert(&imap, 4, (Vec3i){100, 100, 100}); + + c_forpair (n, v, csmap_iv, imap) + printf("%d: { %3d, %3d, %3d }\n", *_.n, _.v->x, _.v->y, _.v->z); + + csmap_iv_drop(&imap); } ``` Output: diff --git a/docs/cspan_api.md b/docs/cspan_api.md index 1e60a526..10565b0f 100644 --- a/docs/cspan_api.md +++ b/docs/cspan_api.md @@ -136,7 +136,7 @@ int main() { ## Example 2 Slicing cspan without and with reducing the rank: ```c -#include <c11/fmt.h> +#include <c11/print.h> #include <stc/cspan.h> using_cspan3(Span, int); // Shorthand to define Span, Span2, and Span3 @@ -154,7 +154,7 @@ int main() puts("\niterate span2 flat:"); c_foreach (i, Span2, span2) - fmt_print(" {}", *i.ref); + print(" {}", *i.ref); puts(""); // slice without reducing rank: @@ -164,26 +164,23 @@ int main() c_forrange (i, ss3.shape[0]) { c_forrange (j, ss3.shape[1]) { c_forrange (k, ss3.shape[2]) - fmt_print(" {:2}", *cspan_at(&ss3, i, j, k)); - fmt_print(" |"); + print(" {:2}", *cspan_at(&ss3, i, j, k)); + print(" |"); } - puts(""); } // slice and reduce rank: Span2 ss2 = cspan_slice(Span2, &span3, {c_ALL}, {3}, {c_ALL}); puts("\niterate ss2 by dimensions:"); c_forrange (i, ss2.shape[0]) { - c_forrange (j, ss2.shape[1]) { - fmt_print(" {:2}", *cspan_at(&ss2, i, j)); - fmt_print(" |"); - } - puts(""); + c_forrange (j, ss2.shape[1]) + print(" {:2}", *cspan_at(&ss2, i, j)); + print(" |"); } puts("\niterate ss2 flat:"); c_foreach (i, Span2, ss2) - fmt_print(" {:2}", *i.ref); + print(" {:2}", *i.ref); puts(""); } ``` diff --git a/docs/csset_api.md b/docs/csset_api.md index 80ee1844..0989fd9b 100644 --- a/docs/csset_api.md +++ b/docs/csset_api.md @@ -80,33 +80,38 @@ csset_X_value csset_X_value_clone(csset_X_value val); ```c #include <stc/cstr.h> +#define i_type SSet #define i_key_str #include <stc/csset.h> int main () { - c_auto (csset_str, first, second, third) - c_auto (csset_str, fourth, fifth) - { - second = c_make(csset_str, {"red", "green", "blue"}); - - c_forlist (i, const char*, {"orange", "pink", "yellow"}) - csset_str_emplace(&third, *i.ref); - - csset_str_emplace(&fourth, "potatoes"); - csset_str_emplace(&fourth, "milk"); - csset_str_emplace(&fourth, "flour"); - - fifth = csset_str_clone(second); - c_foreach (i, csset_str, third) - csset_str_emplace(&fifth, cstr_str(i.ref)); - c_foreach (i, csset_str, fourth) - csset_str_emplace(&fifth, cstr_str(i.ref)); - - printf("fifth contains:\n\n"); - c_foreach (i, csset_str, fifth) - printf("%s\n", cstr_str(i.ref)); - } + SSet second={0}, third={0}, fourth={0}, fifth={0}; + + second = c_make(SSet, {"red", "green", "blue"}); + + c_forlist (i, const char*, {"orange", "pink", "yellow"}) + SSet_emplace(&third, *i.ref); + + SSet_emplace(&fourth, "potatoes"); + SSet_emplace(&fourth, "milk"); + SSet_emplace(&fourth, "flour"); + + // Copy all to fifth: + + fifth = SSet_clone(second); + + c_foreach (i, SSet, third) + SSet_emplace(&fifth, cstr_str(i.ref)); + + c_foreach (i, SSet, fourth) + SSet_emplace(&fifth, cstr_str(i.ref)); + + printf("fifth contains:\n\n"); + c_foreach (i, SSet, fifth) + printf("%s\n", cstr_str(i.ref)); + + c_drop(SSet, &second, &third, &fourth, &fifth); } ``` Output: diff --git a/docs/cstr_api.md b/docs/cstr_api.md index 64099675..64ad002c 100644 --- a/docs/cstr_api.md +++ b/docs/cstr_api.md @@ -160,7 +160,12 @@ char* cstrnstrn(const char* str, const char* search, intptr_t slen, intpt #include <stc/cstr.h> int main() { - c_auto (cstr, s0, s1, full_path) { + cstr s0, s1, full_path; + c_defer( + cstr_drop(&s0), + cstr_drop(&s1), + cstr_drop(&full_path) + ){ s0 = cstr_lit("Initialization without using strlen()."); printf("%s\nLength: %" c_ZI "\n\n", cstr_str(&s0), cstr_size(&s0)); diff --git a/docs/csview_api.md b/docs/csview_api.md index 33e61f0e..ec3bf121 100644 --- a/docs/csview_api.md +++ b/docs/csview_api.md @@ -151,14 +151,15 @@ red Apples int main() { - c_auto (cstr, s1) { - s1 = cstr_lit("hell😀 w😀rld"); - cstr_u8_replace_at(&s1, cstr_find(&s1, "😀rld"), 1, c_sv("ø")); - printf("%s\n", cstr_str(&s1)); - - c_foreach (i, cstr, s1) - printf("%.*s,", c_SV(i.u8.chr)); - } + cstr s1 = cstr_lit("hell😀 w😀rld"); + + cstr_u8_replace_at(&s1, cstr_find(&s1, "😀rld"), 1, c_sv("ø")); + printf("%s\n", cstr_str(&s1)); + + c_foreach (i, cstr, s1) + printf("%.*s,", c_SV(i.u8.chr)); + + cstr_drop(&s1); } ``` Output: @@ -178,6 +179,7 @@ void print_split(csview input, const char* sep) { c_fortoken_sv (i, input, sep) printf("[%.*s]\n", c_SV(i.token)); + puts(""); } #include <stc/cstr.h> @@ -197,13 +199,15 @@ cstack_str string_split(csview input, const char* sep) int main() { print_split(c_sv("//This is a//double-slash//separated//string"), "//"); - puts(""); print_split(c_sv("This has no matching separator"), "xx"); + + cstack_str s = string_split(c_sv("Split,this,,string,now,"), ","); + + c_foreach (i, cstack_str, s) + printf("[%s]\n", cstr_str(i.ref)); puts(""); - c_with (cstack_str s = string_split(c_sv("Split,this,,string,now,"), ","), cstack_str_drop(&s)) - c_foreach (i, cstack_str, s) - printf("[%s]\n", cstr_str(i.ref)); + cstack_str_drop(&s); } ``` Output: diff --git a/docs/cvec_api.md b/docs/cvec_api.md index 68e08cb2..5879bc1f 100644 --- a/docs/cvec_api.md +++ b/docs/cvec_api.md @@ -119,29 +119,29 @@ cvec_X_value cvec_X_value_clone(cvec_X_value val); int main() { // Create a vector containing integers - c_auto (cvec_int, vec) - { - // Add two integers to vector - cvec_int_push(&vec, 25); - cvec_int_push(&vec, 13); - - // Append a set of numbers - c_forlist (i, int, {7, 5, 16, 8}) - cvec_int_push(&vec, *i.ref); - - printf("initial:"); - c_foreach (k, cvec_int, vec) { - printf(" %d", *k.ref); - } - - // Sort the vector - cvec_int_sort(&vec); - - printf("\nsorted:"); - c_foreach (k, cvec_int, vec) { - printf(" %d", *k.ref); - } + cvec_int vec = {0}; + + // Add two integers to vector + cvec_int_push(&vec, 25); + cvec_int_push(&vec, 13); + + // Append a set of numbers + c_forlist (i, int, {7, 5, 16, 8}) + cvec_int_push(&vec, *i.ref); + + printf("initial:"); + c_foreach (k, cvec_int, vec) { + printf(" %d", *k.ref); + } + + // Sort the vector + cvec_int_sort(&vec); + + printf("\nsorted:"); + c_foreach (k, cvec_int, vec) { + printf(" %d", *k.ref); } + cvec_int_drop(&vec); } ``` Output: @@ -212,7 +212,7 @@ User User_clone(User user) { #include <stc/cvec.h> int main(void) { - UVec vec = UVec_init(); + UVec vec = {0}; UVec_push(&vec, (User){cstr_lit("mary"), 0}); UVec_push(&vec, (User){cstr_lit("joe"), 1}); UVec_push(&vec, (User){cstr_lit("admin"), 2}); diff --git a/include/c11/fmt.h b/include/c11/print.h index 193520b1..1302d9cc 100644 --- a/include/c11/fmt.h +++ b/include/c11/print.h @@ -28,7 +28,7 @@ void fmt_destroy(fmt_buffer* buf); * Static linking by default, shared symbols by defining FMT_HEADER / FMT_IMPLEMENT.
* (c) operamint, 2022, MIT License.
-----------------------------------------------------------------------------------
-#include "c11/fmt.h"
+#include "c11/print.h"
int main() {
const double pi = 3.141592653589793;
diff --git a/include/stc/ccommon.h b/include/stc/ccommon.h index b822b9f8..5e163875 100644 --- a/include/stc/ccommon.h +++ b/include/stc/ccommon.h @@ -30,6 +30,7 @@ #include <string.h> #include <assert.h> #include "priv/altnames.h" +#include "priv/raii.h" #define c_NPOS INTPTR_MAX #define c_ZI PRIiPTR @@ -81,7 +82,8 @@ #define c_delete(T, ptr) do { T *_tp = ptr; T##_drop(_tp); free(_tp); } while (0) #define c_static_assert(b) ((int)(0*sizeof(int[(b) ? 1 : -1]))) -#define c_container_of(p, T, m) ((T*)((char*)(p) + 0*sizeof((p) == &((T*)0)->m) - offsetof(T, m))) +#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_swap(T, xp, yp) do { T *_xp = xp, *_yp = yp, \ _tv = *_xp; *_xp = *_yp; *_yp = _tv; } while (0) #define c_sizeof (intptr_t)sizeof @@ -123,7 +125,10 @@ #define c_arraylen(a) (intptr_t)(sizeof(a)/sizeof 0[a]) #define c_litstrlen(literal) (c_sizeof("" literal) - 1) +// Non-owning c-string typedef const char* crawstr; +#define crawstr_clone(s) (s) +#define crawstr_drop(p) ((void)p) #define crawstr_cmp(xp, yp) strcmp(*(xp), *(yp)) #define crawstr_hash(p) cstrhash(*(p)) @@ -132,7 +137,6 @@ typedef const char* crawstr; #define c_sv_2(str, n) (c_LITERAL(csview){str, n}) #define c_SV(sv) (int)(sv).size, (sv).str // print csview: use format "%.*s" -#define c_PAIR(ref) (ref)->first, (ref)->second #define c_ROTL(x, k) (x << (k) | x >> (8*sizeof(x) - (k))) STC_INLINE uint64_t cfasthash(const void* key, intptr_t len) { @@ -195,6 +199,7 @@ STC_INLINE char* cstrnstrn(const char *str, const char *needle, #define c_forrange_4(i, start, stop, step) \ for (long long i=start, _inc=step, _end=(long long)(stop) - (_inc > 0) \ ; (_inc > 0) ^ (i > _end); i += _inc) + #ifndef __cplusplus #define c_forlist(it, T, ...) \ for (struct {T* ref; int size, index;} \ @@ -207,26 +212,6 @@ STC_INLINE char* cstrnstrn(const char *str, const char *needle, it = {._il=__VA_ARGS__, .data=it._il.begin(), .ref=it.data, .size=it._il.size()} \ ; it.index < it.size; ++it.ref, ++it.index) #endif -#define c_with(...) c_MACRO_OVERLOAD(c_with, __VA_ARGS__) -#define c_with_2(declvar, drop) for (declvar, *_i, **_ip = &_i; _ip; _ip = 0, drop) -#define c_with_3(declvar, pred, drop) for (declvar, *_i, **_ip = &_i; _ip && (pred); _ip = 0, drop) -#define c_scope(...) c_MACRO_OVERLOAD(c_scope, __VA_ARGS__) -#define c_scope_2(init, drop) for (int _i = (init, 1); _i; _i = 0, drop) -#define c_scope_3(init, pred, drop) for (int _i = (init, 1); _i && (pred); _i = 0, drop) -#define c_defer(...) for (int _i = 1; _i; _i = 0, __VA_ARGS__) - -#define c_auto(...) c_MACRO_OVERLOAD(c_auto, __VA_ARGS__) -#define c_auto_2(C, a) \ - c_with_2(C a = C##_init(), C##_drop(&a)) -#define c_auto_3(C, a, b) \ - c_with_2(c_EXPAND(C a = C##_init(), b = C##_init()), \ - (C##_drop(&b), C##_drop(&a))) -#define c_auto_4(C, a, b, c) \ - c_with_2(c_EXPAND(C a = C##_init(), b = C##_init(), c = C##_init()), \ - (C##_drop(&c), C##_drop(&b), C##_drop(&a))) -#define c_auto_5(C, a, b, c, d) \ - c_with_2(c_EXPAND(C a = C##_init(), b = C##_init(), c = C##_init(), d = C##_init()), \ - (C##_drop(&d), C##_drop(&c), C##_drop(&b), C##_drop(&a))) #define c_drop(C, ...) \ do { c_forlist (_i, C*, {__VA_ARGS__}) C##_drop(*_i.ref); } while(0) diff --git a/include/stc/priv/raii.h b/include/stc/priv/raii.h new file mode 100644 index 00000000..bb41e0d1 --- /dev/null +++ b/include/stc/priv/raii.h @@ -0,0 +1,27 @@ +#define c_defer(...) \ + for (int _i = 1; _i; _i = 0, __VA_ARGS__) + +#define c_with(...) c_MACRO_OVERLOAD(c_with, __VA_ARGS__) +#define c_with_2(declvar, drop) \ + for (declvar, *_i, **_ip = &_i; _ip; _ip = 0, drop) +#define c_with_3(declvar, pred, drop) \ + for (declvar, *_i, **_ip = &_i; _ip && (pred); _ip = 0, drop) + +#define c_scope(...) c_MACRO_OVERLOAD(c_scope, __VA_ARGS__) +#define c_scope_2(init, drop) \ + for (int _i = (init, 1); _i; _i = 0, drop) +#define c_scope_3(init, pred, drop) \ + for (int _i = (init, 1); _i && (pred); _i = 0, drop) + +#define c_auto(...) c_MACRO_OVERLOAD(c_auto, __VA_ARGS__) +#define c_auto_2(C, a) \ + c_with_2(C a = C##_init(), C##_drop(&a)) +#define c_auto_3(C, a, b) \ + c_with_2(c_EXPAND(C a = C##_init(), b = C##_init()), \ + (C##_drop(&b), C##_drop(&a))) +#define c_auto_4(C, a, b, c) \ + c_with_2(c_EXPAND(C a = C##_init(), b = C##_init(), c = C##_init()), \ + (C##_drop(&c), C##_drop(&b), C##_drop(&a))) +#define c_auto_5(C, a, b, c, d) \ + c_with_2(c_EXPAND(C a = C##_init(), b = C##_init(), c = C##_init(), d = C##_init()), \ + (C##_drop(&d), C##_drop(&c), C##_drop(&b), C##_drop(&a))) diff --git a/misc/benchmarks/various/rust_cmap.c b/misc/benchmarks/various/rust_cmap.c index 83b7dd19..abdb42b0 100644 --- a/misc/benchmarks/various/rust_cmap.c +++ b/misc/benchmarks/various/rust_cmap.c @@ -24,38 +24,40 @@ uint64_t romu_trio(uint64_t s[3]) { int main() { - c_auto (cmap_u64, m) { - const size_t n = 50000000, - mask = (1 << 25) - 1, - ms = CLOCKS_PER_SEC/1000; - cmap_u64_reserve(&m, n); - printf("STC cmap n = %" c_ZU ", mask = 0x%" PRIxMAX "\n", n, mask); - - uint64_t rng[3] = {1872361123, 123879177, 87739234}, sum; - clock_t now = clock(); - c_forrange (n) { - uint64_t key = romu_trio(rng) & mask; - cmap_u64_insert(&m, key, 0).ref->second += 1; - } - printf("insert : %" c_ZU "ms \tsize : %" c_ZU "\n", (clock() - now)/ms, cmap_u64_size(&m)); - - now = clock(); - sum = 0; - c_forrange (key, mask + 1) { sum += cmap_u64_contains(&m, key); } - printf("lookup : %" c_ZU "ms \tsum : %" c_ZU "\n", (clock() - now)/ms, sum); - - now = clock(); - sum = 0; - c_foreach (i, cmap_u64, m) { sum += i.ref->second; } - printf("iterate : %" c_ZU "ms \tsum : %" c_ZU "\n", (clock() - now)/ms, sum); - - uint64_t rng2[3] = {1872361123, 123879177, 87739234}; - now = clock(); - c_forrange (n) { - uint64_t key = romu_trio(rng2) & mask; - cmap_u64_erase(&m, key); - } - printf("remove : %" c_ZU "ms \tsize : %" c_ZU "\n", (clock() - now)/ms, cmap_u64_size(&m)); - printf("press a key:\n"); getchar(); + cmap_u64 m = {0}; + + const size_t n = 50000000, + mask = (1 << 25) - 1, + ms = CLOCKS_PER_SEC/1000; + cmap_u64_reserve(&m, n); + printf("STC cmap n = %" c_ZU ", mask = 0x%" PRIxMAX "\n", n, mask); + + uint64_t rng[3] = {1872361123, 123879177, 87739234}, sum; + clock_t now = clock(); + c_forrange (n) { + uint64_t key = romu_trio(rng) & mask; + cmap_u64_insert(&m, key, 0).ref->second += 1; } + printf("insert : %" c_ZU "ms \tsize : %" c_ZU "\n", (clock() - now)/ms, cmap_u64_size(&m)); + + now = clock(); + sum = 0; + c_forrange (key, mask + 1) { sum += cmap_u64_contains(&m, key); } + printf("lookup : %" c_ZU "ms \tsum : %" c_ZU "\n", (clock() - now)/ms, sum); + + now = clock(); + sum = 0; + c_foreach (i, cmap_u64, m) { sum += i.ref->second; } + printf("iterate : %" c_ZU "ms \tsum : %" c_ZU "\n", (clock() - now)/ms, sum); + + uint64_t rng2[3] = {1872361123, 123879177, 87739234}; + now = clock(); + c_forrange (n) { + uint64_t key = romu_trio(rng2) & mask; + cmap_u64_erase(&m, key); + } + printf("remove : %" c_ZU "ms \tsize : %" c_ZU "\n", (clock() - now)/ms, cmap_u64_size(&m)); + printf("press a key:\n"); getchar(); + + cmap_u64_drop(&m); } diff --git a/misc/examples/arc_containers.c b/misc/examples/arc_containers.c index b621c386..84ba8dda 100644 --- a/misc/examples/arc_containers.c +++ b/misc/examples/arc_containers.c @@ -27,9 +27,12 @@ int main() { - c_auto (Stack, stack) - c_auto (List, list) - { + 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; @@ -62,13 +65,13 @@ int main() // 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) diff --git a/misc/examples/arc_demo.c b/misc/examples/arc_demo.c index 867cfc83..88555177 100644 --- a/misc/examples/arc_demo.c +++ b/misc/examples/arc_demo.c @@ -22,36 +22,37 @@ void int_drop(int* x) { int main() { - c_auto (cvec_Arc, vec) // declare and init vec, call cvec_Arc_drop() at scope exit - c_auto (csset_Arc, set) // declare and init set, call csset_Arc_drop() at scope exit - { - const int years[] = {2021, 2012, 2022, 2015}; - c_forrange (i, c_ARRAYLEN(years)) - cvec_Arc_push(&vec, Arc_from(years[i])); - - printf("vec:"); - c_foreach (i, cvec_Arc, vec) printf(" %d", *i.ref->get); - puts(""); - - // add odd numbers from vec to set - 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); - - c_with (Arc p = Arc_clone(vec.data[0]), Arc_drop(&p)) { - printf("\n%d is now owned by %ld objects\n", *p.get, *p.use_count); - } - - puts("\nDone"); - } + const int years[] = {2021, 2012, 2022, 2015}; + + cvec_Arc vec = {0}; + c_forrange (i, c_ARRAYLEN(years)) + cvec_Arc_push(&vec, Arc_from(years[i])); + + 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 index 9c85d3ab..3bf41559 100644 --- a/misc/examples/arcvec_erase.c +++ b/misc/examples/arcvec_erase.c @@ -15,38 +15,36 @@ void show_drop(int* x) { printf("drop: %d\n", *x); } int main() { - c_auto (Vec, vec) - { - vec = c_make(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 vec = c_make(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 index 10e45d3c..6c850b08 100644 --- a/misc/examples/astar.c +++ b/misc/examples/astar.c @@ -78,12 +78,16 @@ point_key_cmp(const point* a, const point* b) cdeq_point astar(cstr* maze, int width) { - cdeq_point path = cdeq_point_init(); + cdeq_point ret_path = {0}; - c_auto (cpque_point, front) - c_auto (csmap_pstep, from) - c_auto (csmap_pcost, costs) - { + 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); @@ -120,18 +124,18 @@ astar(cstr* maze, int width) point current = goal; while (!point_equal(¤t, &start)) { - cdeq_point_push_front(&path, current); + cdeq_point_push_front(&ret_path, current); current = *csmap_pstep_at(&from, current); } - cdeq_point_push_front(&path, start); + cdeq_point_push_front(&ret_path, start); } - return path; + return ret_path; } int main(void) { - c_with (cstr maze = cstr_lit( + cstr maze = cstr_lit( "#########################################################################\n" "# # # # # # #\n" "# # ######### # ##### ######### ##### ##### ##### # ! #\n" @@ -154,15 +158,16 @@ main(void) "# # # # # # # # # #\n" "# @ # ##### ##### ##### ######### ##### # ######### # #\n" "# # # # # # #\n" - "#########################################################################\n"), cstr_drop(&maze)) - { - int width = (int)cstr_find(&maze, "\n") + 1; - c_with (cdeq_point path = astar(&maze, width), cdeq_point_drop(&path)) - { - c_foreach (it, cdeq_point, path) - cstr_data(&maze)[point_index(it.ref)] = 'x'; - - printf("%s", cstr_str(&maze)); - } - } + "#########################################################################\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 index cb627ef8..2b52cc48 100644 --- a/misc/examples/birthday.c +++ b/misc/examples/birthday.c @@ -18,16 +18,15 @@ static void test_repeats(void) printf("birthday paradox: value range: 2^%d, testing repeats of 2^%d values\n", BITS, BITS_TEST); stc64_t rng = stc64_new(seed); - c_auto (cmap_ic, m) - { - cmap_ic_reserve(&m, N); - c_forrange (i, N) { - uint64_t k = stc64_rand(&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 m = cmap_ic_with_capacity(N); + c_forrange (i, N) { + uint64_t k = stc64_rand(&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 @@ -42,22 +41,23 @@ void test_distribution(void) stc64_t rng = stc64_new(seed); const size_t N = 1ull << BITS ; - c_auto (cmap_x, map) { - c_forrange (N) { - uint64_t k = stc64_rand(&rng); - cmap_x_insert(&map, k & 0xf, 0).ref->second += 1; - } + cmap_x map = {0}; + c_forrange (N) { + uint64_t k = stc64_rand(&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; + 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)); - } + 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() diff --git a/misc/examples/bits.c b/misc/examples/bits.c index 6f28c52d..1323d4e7 100644 --- a/misc/examples/bits.c +++ b/misc/examples/bits.c @@ -3,7 +3,12 @@ int main(void) { - c_with (cbits set = cbits_with_size(23, true), cbits_drop(&set)) { + cbits set = cbits_with_size(23, true); + cbits s2; + c_defer( + cbits_drop(&set), + cbits_drop(&s2) + ){ printf("count %" c_ZI ", %" c_ZI "\n", cbits_count(&set), cbits_size(&set)); cbits s1 = cbits_from("1110100110111"); char buf[256]; @@ -35,27 +40,27 @@ int main(void) printf("%d", cbits_test(&set, i)); puts(""); - c_with (cbits s2 = cbits_clone(set), cbits_drop(&s2)) { - 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("%4" c_ZI ": ", 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("%4" c_ZI ": ", cbits_size(&set)); + c_forrange (i, cbits_size(&set)) + printf("%d", cbits_test(&set, i)); + puts(""); } } diff --git a/misc/examples/books.c b/misc/examples/books.c index 098771ae..e43c0bc3 100644 --- a/misc/examples/books.c +++ b/misc/examples/books.c @@ -8,8 +8,10 @@ // would be `HashMap<String, String>` in this example). int main() { - c_auto (cmap_str, book_reviews) - { + cmap_str book_reviews = {0}; + c_defer( + cmap_str_drop(&book_reviews) + ){ // Review some books. cmap_str_emplace(&book_reviews, "Adventures of Huckleberry Finn", diff --git a/misc/examples/box.c b/misc/examples/box.c index da13501f..9954883c 100644 --- a/misc/examples/box.c +++ b/misc/examples/box.c @@ -37,32 +37,32 @@ void Person_drop(Person* p) { int main() { - c_auto (Persons, vec) - c_auto (PBox, p, q) - { - p = PBox_from(Person_make("Laura", "Palmer")); - q = PBox_clone(p); - cstr_assign(&q.get->name, "Leland"); + 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)); + 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")); + 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)); + // 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(""); + 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. - c_with (Person a = Person_make("Audrey", "Home"), Person_drop(&a)) { - 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)); - } - 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 index f7d21976..cba255d2 100644 --- a/misc/examples/box2.c +++ b/misc/examples/box2.c @@ -40,31 +40,27 @@ cbox_Point boxed_origin(void) { int main(void) { // Stack allocated variables Point point = origin(); - Rectangle rectangle = (Rectangle){ + Rectangle rectangle = { .top_left = origin(), .bottom_right = { .x=3.0, .y=-4.0 } }; - // Declare RAII'ed box objects - c_auto (cbox_Rectangle, boxed_rectangle) - c_auto (cbox_Point, boxed_point) - c_auto (BoxBoxPoint, box_in_a_box) - { - // Heap allocated rectangle - boxed_rectangle = cbox_Rectangle_make((Rectangle){ - .top_left = origin(), - .bottom_right = { .x=3.0, .y=-4.0 } - }); + // Heap allocated rectangle + cbox_Rectangle boxed_rectangle = cbox_Rectangle_make((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()); - // The output of functions can be boxed - boxed_point = cbox_Point_make(origin()); + // Can use from(raw) and toraw instead: + BoxBoxPoint box_in_a_box = BoxBoxPoint_from(origin()); - // Double indirection - //box_in_a_box = BoxBoxPoint_make(boxed_origin()); - //printf("box_in_a_box: x = %g\n", box_in_a_box.get->get->x); - - // Can use from(raw) and toraw instead: - 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", diff --git a/misc/examples/city.c b/misc/examples/city.c deleted file mode 100644 index 67471cfb..00000000 --- a/misc/examples/city.c +++ /dev/null @@ -1,92 +0,0 @@ -#include <stc/cstr.h> - -typedef struct { - cstr name; - cstr country; - float lat, lon; - int population; -} City; - -int City_cmp(const City* a, const City* b); -uint64_t City_hash(const City* a); -City City_clone(City c); -void City_drop(City* c); - -#define i_type CityArc -#define i_valclass City -#include <stc/cbox.h> -//#include <stc/carc.h> // try instead of cbox.h - -#define i_type Cities -#define i_keyboxed CityArc -#include <stc/cvec.h> - -#define i_type CityMap -#define i_key int -#define i_valboxed CityArc -#include <stc/csmap.h> - - -int City_cmp(const City* a, const City* b) { - int c = cstr_cmp(&a->name, &b->name); - return c ? c : cstr_cmp(&a->country, &b->country); -} - -uint64_t City_hash(const City* a) { - return cstr_hash(&a->name) ^ cstr_hash(&a->country); -} - -City City_clone(City c) { - c.name = cstr_clone(c.name); - c.country = cstr_clone(c.country); - return c; -} - -void City_drop(City* c) { - printf("drop %s\n", cstr_str(&c->name)); - c_drop(cstr, &c->name, &c->country); -} - - -int main(void) -{ - c_auto (Cities, cities, copy) - c_auto (CityMap, map) - { - // Create a cvec with smart pointers to City objects! - cities = c_make(Cities, { - {cstr_lit("New York"), cstr_lit("US"), 40.71427f, -74.00597f, 8804190}, - {cstr_lit("Paris"), cstr_lit("France"), 48.85341f, 2.3488f, 2138551}, - {cstr_lit("Berlin"), cstr_lit("Germany"), 52.52437f, 13.41053f, 3426354}, - {cstr_lit("London"), cstr_lit("UK"), 51.50853f, -0.12574f, 8961989}, - }); - - Cities_sort(&cities); - - printf("Vec:\n"); - c_foreach (c, Cities, cities) - printf("city: %8s, %8d, use: %ld\n", cstr_str(&c.ref->get->name), - c.ref->get->population, - CityArc_use_count(c.ref)); - puts(""); - copy = Cities_clone(cities); // share each city! - - int k = 0, id[] = {8, 4, 3, 9, 2, 5}; - c_foreach (i, Cities, cities) - CityMap_insert(&map, id[k++], CityArc_clone(*i.ref)); - - Cities_pop(&cities); - Cities_pop(&cities); - - printf("Vec:\n"); - c_foreach (c, Cities, cities) - printf("city: %8s, %8d, use: %ld\n", cstr_str(&c.ref->get->name), - c.ref->get->population, - CityArc_use_count(c.ref)); - printf("\nMap:\n"); - c_forpair (id, city, CityMap, map) - printf("city: %8s, %8d, use: %ld, id:%d\n", cstr_str(&_.city->get->name), - _.city->get->population, CityArc_use_count(_.city), *_.id); - puts(""); - } -} diff --git a/misc/examples/complex.c b/misc/examples/complex.c index e73d7aa1..7dde981d 100644 --- a/misc/examples/complex.c +++ b/misc/examples/complex.c @@ -31,25 +31,20 @@ int main() { - c_auto (MapMap, mmap) - { - FloatStack stack = FloatStack_with_size(10, 0); - - // Put in some data in the structures - stack.data[3] = 3.1415927f; - printf("stack size: %" c_ZI "\n", FloatStack_size(&stack)); - - StackList list = StackList_init(); - StackList_push_back(&list, stack); - - ListMap lmap = ListMap_init(); - ListMap_insert(&lmap, 42, list); - MapMap_insert(&mmap, cstr_from("first"), lmap); - - // 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", *FloatStack_at(stack_p, 3)); // pi - } + 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", *FloatStack_at(stack_p, 3)); // pi + + MapMap_drop(&mmap); } diff --git a/misc/examples/convert.c b/misc/examples/convert.c index 160812b7..0f09e830 100644 --- a/misc/examples/convert.c +++ b/misc/examples/convert.c @@ -13,10 +13,17 @@ int main() { - c_auto (cmap_str, map, mclone) - c_auto (cvec_str, keys, values) - c_auto (clist_str, list) - { + 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_make(cmap_str, { {"green", "#00ff00"}, {"blue", "#0000ff"}, diff --git a/misc/examples/csmap_erase.c b/misc/examples/csmap_erase.c index a3bd250b..697e6c09 100644 --- a/misc/examples/csmap_erase.c +++ b/misc/examples/csmap_erase.c @@ -17,68 +17,65 @@ void printmap(mymap m) int main() { - c_auto (mymap, m1) - { - // 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")); + mymap m1 = {0}; - 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, 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")); - c_auto (mymap, m2) - { - // Fill in some data to test with, one at a time - m2 = c_make(mymap, { - {10, "Bob"}, - {11, "Rob"}, - {12, "Robert"}, - {13, "Bert"}, - {14, "Bobby"}, - }); + 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); - 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); + // Fill in some data to test with + mymap m2 = c_make(mymap, { + {10, "Bob"}, + {11, "Rob"}, + {12, "Robert"}, + {13, "Bert"}, + {14, "Bobby"}, + }); - 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); - } + 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); - c_auto (mymap, m3) - { - // 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("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); - 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); - } + 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 index 863cdea0..c417567a 100644 --- a/misc/examples/csmap_find.c +++ b/misc/examples/csmap_find.c @@ -42,32 +42,32 @@ void findit(csmap_istr c, csmap_istr_key val) int main() { - c_auto (csmap_istr, m1) - c_auto (cvec_istr, v) - { - m1 = c_make(csmap_istr, {{40, "Zr"}, {45, "Rh"}}); + csmap_istr m1 = c_make(csmap_istr, {{40, "Zr"}, {45, "Rh"}}); + cvec_istr v = {0}; - puts("The starting map m1 is (key, value):"); - print_collection_csmap_istr(&m1); + puts("The starting map m1 is (key, value):"); + print_collection_csmap_istr(&m1); - typedef cvec_istr_value pair; - cvec_istr_push(&v, (pair){43, "Tc"}); - cvec_istr_push(&v, (pair){41, "Nb"}); - cvec_istr_push(&v, (pair){46, "Pd"}); - cvec_istr_push(&v, (pair){42, "Mo"}); - cvec_istr_push(&v, (pair){44, "Ru"}); - cvec_istr_push(&v, (pair){44, "Ru"}); // attempt a duplicate + typedef cvec_istr_value pair; + cvec_istr_push(&v, (pair){43, "Tc"}); + cvec_istr_push(&v, (pair){41, "Nb"}); + cvec_istr_push(&v, (pair){46, "Pd"}); + cvec_istr_push(&v, (pair){42, "Mo"}); + cvec_istr_push(&v, (pair){44, "Ru"}); + cvec_istr_push(&v, (pair){44, "Ru"}); // attempt a duplicate - puts("Inserting the following vector data into m1:"); - print_collection_cvec_istr(&v); + 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, c_PAIR(i.ref)); + 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); - } + 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 index 64d71b12..3da245c7 100644 --- a/misc/examples/csmap_insert.c +++ b/misc/examples/csmap_insert.c @@ -1,13 +1,11 @@ -#include <stc/cstr.h> - // 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 <stc/csmap.h> +#include <stc/cstr.h> #define i_key int #define i_val_str #define i_tag istr // Map of int => cstr @@ -33,77 +31,77 @@ void print_istr(csmap_istr map) { int main() { // insert single values - c_auto (csmap_ii, m1) { - csmap_ii_insert(&m1, 1, 10); - csmap_ii_insert(&m1, 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); + csmap_ii m1 = {0}; + csmap_ii_insert(&m1, 1, 10); + csmap_ii_push(&m1, (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(""); } + 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 - c_auto (csmap_ii, m2) - c_auto (cvec_ii, v) { - typedef cvec_ii_value ipair; - cvec_ii_push(&v, (ipair){43, 294}); - cvec_ii_push(&v, (ipair){41, 262}); - cvec_ii_push(&v, (ipair){45, 330}); - cvec_ii_push(&v, (ipair){42, 277}); - cvec_ii_push(&v, (ipair){44, 311}); - - 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"); - } + csmap_ii m2 = {0}; + cvec_ii v = {0}; + typedef cvec_ii_value ipair; + cvec_ii_push(&v, (ipair){43, 294}); + cvec_ii_push(&v, (ipair){41, 262}); + cvec_ii_push(&v, (ipair){45, 330}); + cvec_ii_push(&v, (ipair){42, 277}); + cvec_ii_push(&v, (ipair){44, 311}); + + 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 - c_auto (csmap_istr, m3) { - 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_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(""); - c_auto (csmap_ii, m4) { - // Insert the elements from an initializer_list - m4 = c_make(csmap_ii, {{4, 44}, {2, 22}, {3, 33}, {1, 11}, {5, 55}}); - puts("After initializer_list insertion, m4 contains:"); - print_ii(m4); - puts(""); - } + csmap_ii m4 = {0}; + // Insert the elements from an initializer_list + m4 = c_make(csmap_ii, {{4, 44}, {2, 22}, {3, 33}, {1, 11}, {5, 55}}); + 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 index cf94156c..9fa40682 100644 --- a/misc/examples/csset_erase.c +++ b/misc/examples/csset_erase.c @@ -5,38 +5,37 @@ int main() { - c_auto (csset_int, set) - { - set = c_make(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 set = c_make(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); +}
\ No newline at end of file diff --git a/misc/examples/cstr_match.c b/misc/examples/cstr_match.c index 6682c4ba..58cf8884 100644 --- a/misc/examples/cstr_match.c +++ b/misc/examples/cstr_match.c @@ -4,20 +4,22 @@ int main() { - c_with (cstr ss = cstr_lit("The quick brown fox jumps over the lazy dog.JPG"), cstr_drop(&ss)) { - intptr_t pos = cstr_find_at(&ss, 0, "brown"); - printf("%" c_ZI " [%s]\n", pos, pos == c_NPOS ? "<NULL>" : 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 ss = cstr_lit("The quick brown fox jumps over the lazy dog.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)); - } + intptr_t pos = cstr_find_at(&ss, 0, "brown"); + printf("%" c_ZI " [%s]\n", pos, pos == c_NPOS ? "<NULL>" : 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 index 2a7f3888..de92e378 100644 --- a/misc/examples/demos.c +++ b/misc/examples/demos.c @@ -2,30 +2,29 @@ void stringdemo1() { - printf("\nSTRINGDEMO1\n"); - c_with (cstr cs = cstr_lit("one-nine-three-seven-five"), cstr_drop(&cs)) - { - printf("%s.\n", cstr_str(&cs)); + 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_insert(&cs, 3, "-two"); + printf("%s.\n", cstr_str(&cs)); - cstr_erase(&cs, 7, 5); // -nine - 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_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)); + 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")); + 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)); - } + // 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_val int64_t @@ -34,23 +33,22 @@ void stringdemo1() void vectordemo1() { - printf("\nVECTORDEMO1\n"); - c_with (cvec_ix bignums = cvec_ix_with_capacity(100), cvec_ix_drop(&bignums)) - { - 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 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_val_str @@ -58,52 +56,51 @@ void vectordemo1() void vectordemo2() { - printf("\nVECTORDEMO2\n"); - c_auto (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", 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 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_val int #define i_tag ix -#define i_extern // define _clist_mergesort() once #include <stc/clist.h> void listdemo1() { - printf("\nLISTDEMO1\n"); - c_auto (clist_ix, nums, 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 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); - } + 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 @@ -112,8 +109,7 @@ void listdemo1() void setdemo1() { - printf("\nSETDEMO1\n"); - cset_i nums = cset_i_init(); + cset_i nums = {0}; cset_i_insert(&nums, 8); cset_i_insert(&nums, 11); @@ -129,8 +125,7 @@ void setdemo1() void mapdemo1() { - printf("\nMAPDEMO1\n"); - cmap_ii nums = cmap_ii_init(); + 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)); @@ -144,21 +139,20 @@ void mapdemo1() void mapdemo2() { - printf("\nMAPDEMO2\n"); - c_auto (cmap_si, nums) - { - 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 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 @@ -167,8 +161,7 @@ void mapdemo2() void mapdemo3() { - printf("\nMAPDEMO3\n"); - cmap_str table = cmap_str_init(); + cmap_str table = {0}; cmap_str_emplace(&table, "Map", "test"); cmap_str_emplace(&table, "Make", "my"); cmap_str_emplace(&table, "Sunny", "day"); @@ -182,17 +175,18 @@ void mapdemo3() 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() { - stringdemo1(); - vectordemo1(); - vectordemo2(); - listdemo1(); - setdemo1(); - mapdemo1(); - mapdemo2(); - mapdemo3(); + 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/forfilter.c b/misc/examples/forfilter.c index cd6d59cc..fdf8be6f 100644 --- a/misc/examples/forfilter.c +++ b/misc/examples/forfilter.c @@ -21,30 +21,28 @@ void demo1(void) { - c_auto (IVec, vec) { - c_forlist (i, int, {0, 1, 2, 3, 4, 5, 80, 6, 7, 80, 8, 9, 80, - 10, 11, 12, 13, 14, 15, 80, 16, 17}) - IVec_push(&vec, *i.ref); - - puts("demo1:"); - c_forfilter (i, IVec, vec, flt_skipValue(i, 80)) - printf(" %d", *i.ref); - puts(""); - - int res, sum = 0; - c_forfilter (i, IVec, vec, - c_flt_skipwhile(i, *i.ref != 80) && - c_flt_skip(i, 1) && - c_flt_skipwhile(i, *i.ref != 80) && - flt_isEven(i) && - flt_skipValue(i, 80) && - c_flt_take(i, 5) // short-circuit - ){ - sum += res = flt_square(i); - printf(" %d", res); - } - printf("\n sum: %d\n", sum); + IVec vec = c_make(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 res, sum = 0; + c_forfilter (i, IVec, vec, + c_flt_skipwhile(i, *i.ref != 80) && + c_flt_skip(i, 1) && + c_flt_skipwhile(i, *i.ref != 80) && + flt_isEven(i) && + flt_skipValue(i, 80) && + c_flt_take(i, 5) // short-circuit + ){ + sum += res = flt_square(i); + printf(" %d", res); } + + printf("\n sum: %d\n", sum); + IVec_drop(&vec); } @@ -62,18 +60,19 @@ fn main() { void demo2(void) { - c_auto (IVec, vector) { - puts("demo2:"); - 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 vector = {0}; + + c_forfilter (x, crange, crange_obj(INT64_MAX), + 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: @@ -91,42 +90,45 @@ fn main() { */ void demo3(void) { - c_auto (SVec, words, words_containing_i) { - const char* sentence = "This is a sentence in C99."; - c_fortoken (w, sentence, " ") - SVec_push(&words, *w.ref); - - c_forfilter (w, SVec, words, - csview_contains(*w.ref, "i")) - SVec_push(&words_containing_i, *w.ref); - - puts("demo3:"); - c_foreach (w, SVec, words_containing_i) - printf(" %.*s", c_SV(*w.ref)); - puts(""); - } + 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 - c_auto (cstr, out) { - 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); - } - puts("demo4:"); - printf(" %s\n", cstr_str(&out)); + 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) - puts("demo5:"); 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)) && @@ -134,14 +136,15 @@ void demo5(void) flt_even(i) && c_flt_take(i,5)) printf(" %lld", *i.ref); + puts(""); } int main(void) { - demo1(); - demo2(); - demo3(); - demo4(); - demo5(); + 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 index 2fe21c8b..54b49485 100644 --- a/misc/examples/forloops.c +++ b/misc/examples/forloops.c @@ -25,7 +25,6 @@ int main() 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);
@@ -35,48 +34,43 @@ int main() printf(" %s", *i.ref);
puts("");
+ IVec vec = c_make(IVec, {12, 23, 453, 65, 113, 215, 676, 34, 67, 20, 27, 66, 189, 45, 280, 199});
+ IMap map = c_make(IMap, {{12, 23}, {453, 65}, {676, 123}, {34, 67}});
+
+ puts("\n\nc_foreach:");
+ c_foreach (i, IVec, vec)
+ printf(" %d", *i.ref);
+
+ puts("\n\nc_foreach_r: reverse");
+ c_foreach_r (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);
+
+ puts("\n\nc_forfilter 1:");
+ c_forfilter (i, IVec, vec, c_flt_take(i, 3))
+ printf(" %d", *i.ref);
+
+ #define isOdd(i) (*i.ref & 1)
+
+ puts("\n\nc_forfilter 2:");
+ c_forfilter (i, IVec, vec,
+ c_flt_skipwhile(i, *i.ref != 65) &&
+ c_flt_takewhile(i, *i.ref != 280) &&
+ c_flt_skipwhile(i, isOdd(i)) &&
+ isOdd(i) &&
+ c_flt_skip(i, 2) &&
+ c_flt_take(i, 2))
+ printf(" %d", *i.ref);
+ puts("");
+ // 189
- c_auto (IVec, vec)
- c_auto (IMap, map)
- {
- c_forlist (i, int, {12, 23, 453, 65, 113, 215, 676, 34, 67, 20, 27, 66, 189, 45, 280, 199})
- IVec_push(&vec, *i.ref);
-
- c_forlist (i, IMap_value, {{12, 23}, {453, 65}, {676, 123}, {34, 67}})
- IMap_push(&map, *i.ref);
-
- puts("\n\nc_foreach:");
- c_foreach (i, IVec, vec)
- printf(" %d", *i.ref);
-
- puts("\n\nc_foreach_r: reverse");
- c_foreach_r (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);
-
- puts("\n\nc_forfilter 1:");
- c_forfilter (i, IVec, vec, c_flt_take(i, 3))
- printf(" %d", *i.ref);
-
- #define isOdd(i) (*i.ref & 1)
-
- puts("\n\nc_forfilter 2:");
- c_forfilter (i, IVec, vec,
- c_flt_skipwhile(i, *i.ref != 65) &&
- c_flt_takewhile(i, *i.ref != 280) &&
- c_flt_skipwhile(i, isOdd(i)) &&
- isOdd(i) &&
- c_flt_skip(i, 2) &&
- c_flt_take(i, 2))
- printf(" %d", *i.ref);
- puts("");
- // 189
- }
+ IVec_drop(&vec);
+ IMap_drop(&map);
}
diff --git a/misc/examples/functor.c b/misc/examples/functor.c index 6d42c4f8..8952c710 100644 --- a/misc/examples/functor.c +++ b/misc/examples/functor.c @@ -51,18 +51,17 @@ int main() IPQueue q1 = {ipque_init(), int_less}; // Max priority queue IPQueue minq1 = {ipque_init(), int_greater}; // Min priority queue IPQueue q5 = {ipque_init(), int_lambda}; // Using lambda to compare elements. - c_defer (ipque_drop(&q1.Q), ipque_drop(&minq1.Q), ipque_drop(&q5.Q)) - { - c_forrange (i, n) - ipque_push(&q1.Q, data[i]); - print_queue("q1", q1); + c_forrange (i, n) + ipque_push(&q1.Q, data[i]); + print_queue("q1", q1); - c_forrange (i, n) - ipque_push(&minq1.Q, data[i]); - print_queue("minq1", minq1); + c_forrange (i, n) + ipque_push(&minq1.Q, data[i]); + print_queue("minq1", minq1); - c_forrange (i, n) - ipque_push(&q5.Q, data[i]); - print_queue("q5", q5); - } + c_forrange (i, n) + ipque_push(&q5.Q, data[i]); + print_queue("q5", q5); + + c_drop(ipque, &q1.Q, &minq1.Q, &q5.Q); } diff --git a/misc/examples/gauss1.c b/misc/examples/gauss1.c index 40d0981f..67871aa9 100644 --- a/misc/examples/gauss1.c +++ b/misc/examples/gauss1.c @@ -29,28 +29,30 @@ int main() stc64_normalf_t dist = stc64_normalf_new(Mean, StdDev); // Create and init histogram vec and map with defered destructors: - c_auto (cvec_ii, histvec) - c_auto (cmap_ii, histmap) - { - c_forrange (N) { - int index = (int)round( stc64_normalf(&rng, &dist) ); - cmap_ii_insert(&histmap, index, 0).ref->second += 1; - } + cvec_ii histvec = {0}; + cmap_ii histmap = {0}; + + c_forrange (N) { + int index = (int)round( stc64_normalf(&rng, &dist) ); + cmap_ii_insert(&histmap, index, 0).ref->second += 1; + } - // Transfer map to vec and sort it by map keys. - c_foreach (i, cmap_ii, histmap) - cvec_ii_push(&histvec, (cmap_ii_value){i.ref->first, i.ref->second}); + // Transfer map to vec and sort it by map keys. + c_foreach (i, cmap_ii, histmap) + cvec_ii_push(&histvec, (cmap_ii_value){i.ref->first, i.ref->second}); - cvec_ii_sort(&histvec); + cvec_ii_sort(&histvec); - // Print the gaussian bar chart - c_foreach (i, cvec_ii, histvec) { - int n = (int)(i.ref->second * StdDev * Scale * 2.5 / (double)N); - if (n > 0) { - printf("%4d ", i.ref->first); - c_forrange (n) printf("*"); - puts(""); - } + // Print the gaussian bar chart + c_foreach (i, cvec_ii, histvec) { + int n = (int)(i.ref->second * StdDev * Scale * 2.5 / (double)N); + if (n > 0) { + printf("%4d ", i.ref->first); + c_forrange (n) printf("*"); + puts(""); } } + + cvec_ii_drop(&histvec); + cmap_ii_drop(&histmap); } diff --git a/misc/examples/gauss2.c b/misc/examples/gauss2.c index c531e5e3..79397f0c 100644 --- a/misc/examples/gauss2.c +++ b/misc/examples/gauss2.c @@ -22,21 +22,22 @@ int main() stc64_normalf_t dist = stc64_normalf_new(Mean, StdDev); // Create and init histogram map with defered destruct - c_auto (csmap_int, mhist) - { - c_forrange (N) { - int index = (int) round( stc64_normalf(&rng, &dist) ); - csmap_int_insert(&mhist, index, 0).ref->second += 1; - } + csmap_int mhist = {0}; + cstr bar = {0}; + + c_forrange (N) { + int index = (int) round( stc64_normalf(&rng, &dist) ); + csmap_int_insert(&mhist, index, 0).ref->second += 1; + } - // Print the gaussian bar chart - c_auto (cstr, bar) - c_forpair (index, count, csmap_int, mhist) { - int n = (int)((float)*_.count * StdDev * Scale * 2.5f / (float)N); - if (n > 0) { - cstr_resize(&bar, n, '*'); - printf("%4d %s\n", *_.index, cstr_str(&bar)); - } + // Print the gaussian bar chart + c_forpair (index, count, csmap_int, mhist) { + int n = (int)((float)*_.count * StdDev * Scale * 2.5f / (float)N); + if (n > 0) { + cstr_resize(&bar, n, '*'); + printf("%4d %s\n", *_.index, cstr_str(&bar)); } } + cstr_drop(&bar); + csmap_int_drop(&mhist); } diff --git a/misc/examples/hashmap.c b/misc/examples/hashmap.c index f59ed824..47a3bcff 100644 --- a/misc/examples/hashmap.c +++ b/misc/examples/hashmap.c @@ -17,32 +17,33 @@ const char* call(const char* number) { } int main(void) { - c_auto (cmap_str, contacts) - { - 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 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/inits.c b/misc/examples/inits.c index 3d03ee91..7530dd08 100644 --- a/misc/examples/inits.c +++ b/misc/examples/inits.c @@ -36,79 +36,73 @@ int main(void) { // CVEC FLOAT / PRIORITY QUEUE - c_auto (cpque_f, floats) { - 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 ", *cpque_f_top(&floats)); - cpque_f_pop(&floats); - } - puts("\n"); + 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 ", *cpque_f_top(&floats)); + cpque_f_pop(&floats); } + puts("\n"); + cpque_f_drop(&floats); // CMAP ID int year = 2020; - c_auto (cmap_id, idnames) { - 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 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 - c_auto (cmap_cnt, countries) - { - countries = c_make(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 countries = c_make(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 - c_auto (cvec_ip, pairs1) { - pairs1 = c_make(cvec_ip, {{5, 6}, {3, 4}, {1, 2}, {7, 8}}); + cvec_ip pairs1 = c_make(cvec_ip, {{5, 6}, {3, 4}, {1, 2}, {7, 8}}); + cvec_ip_sort(&pairs1); - cvec_ip_sort(&pairs1); - - c_foreach (i, cvec_ip, pairs1) - printf("(%d %d) ", i.ref->x, i.ref->y); - puts(""); - } + c_foreach (i, cvec_ip, pairs1) + printf("(%d %d) ", i.ref->x, i.ref->y); + puts(""); + cvec_ip_drop(&pairs1); // CLIST PAIR - c_auto (clist_ip, pairs2) { - pairs2 = c_make(clist_ip, {{5, 6}, {3, 4}, {1, 2}, {7, 8}}); + clist_ip pairs2 = c_make(clist_ip, {{5, 6}, {3, 4}, {1, 2}, {7, 8}}); + clist_ip_sort(&pairs2); - clist_ip_sort(&pairs2); - - c_foreach (i, clist_ip, pairs2) - printf("(%d %d) ", i.ref->x, i.ref->y); - puts(""); - } + 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 index 5f9f8d07..093cb36e 100644 --- a/misc/examples/intrusive.c +++ b/misc/examples/intrusive.c @@ -1,55 +1,34 @@ -// Example of intrusive/shared list-nodes by using the node API. +// Example of clist using the node API. #include <stdio.h> -#define i_type Inner +#define i_type List #define i_val int -#define i_extern // implement Inner_sort() #include <stc/clist.h> -#define i_type Outer -#define i_val Inner_node -#define i_opt c_no_cmp // no elem. comparison -#include <stc/clist.h> - -void printLists(Inner inner, Outer outer) { - printf(" inner:"); - c_foreach (i, Inner, inner) - printf(" %d", *i.ref); - - printf("\n outer:"); - c_foreach (i, Outer, outer) - printf(" %d", i.ref->value); - puts(""); +void printList(List list) { + printf("list:"); + c_foreach (i, List, list) + printf(" %d", *i.ref); + puts(""); } -int main() -{ - c_auto (Outer, outer) - { - Inner inner = Inner_init(); // do not destroy, outer will destroy the shared nodes. - - c_forlist (i, int, {6, 9, 3, 1, 7, 4, 5, 2, 8}) { - Inner_node* node = Outer_push_back(&outer, (Inner_node){0}); - node->value = *i.ref; - } - - c_foreach (i, Outer, outer) - Inner_push_back_node(&inner, i.ref); - - printLists(inner, outer); - - puts("Sort inner"); - Inner_sort(&inner); +int main() { + 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})); - printLists(inner, outer); + printList(list); - puts("Remove odd numbers from inner list"); + puts("Sort list"); + List_sort(&list); + printList(list); - c_foreach (i, Inner, inner) - if (*i.ref & 1) - Inner_unlink_after_node(&inner, i.prev); + puts("Remove odd numbers from list list"); + c_foreach (i, List, list) + if (*i.ref & 1) + List_unlink_after_node(&list, i.prev); + printList(list); - printLists(inner, outer); - } + List_drop(&list); } diff --git a/misc/examples/list.c b/misc/examples/list.c index 027c5adc..9f0b2504 100644 --- a/misc/examples/list.c +++ b/misc/examples/list.c @@ -1,69 +1,64 @@ #include <stdio.h> #include <time.h> -#include <stc/calgo.h> +#include <stc/algo/filter.h> #include <stc/crandom.h> +#define i_type DList #define i_val double -#define i_tag fx #include <stc/clist.h> int main() { const int n = 3000000; + DList list = {0}; - c_auto (clist_fx, list) - { - stc64_t rng = stc64_new(1234567); - stc64_uniformf_t dist = stc64_uniformf_new(100.0f, n); - int m = 0; - c_forrange (n) - clist_fx_push_back(&list, stc64_uniformf(&rng, &dist)), ++m; + stc64_t rng = stc64_new(1234567); + stc64_uniformf_t dist = stc64_uniformf_new(100.0f, n); + int m = 0; + c_forrange (n) + DList_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); + 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, clist_fx, list, c_flt_take(i, 10)) - printf("%8d: %10f\n", c_flt_last(i), *i.ref); + c_forfilter (i, DList, list, c_flt_take(i, 10)) + printf("%8d: %10f\n", c_flt_last(i), *i.ref); - puts("sort"); - clist_fx_sort(&list); // mergesort O(n*log n) - puts("sorted"); + puts("sort"); + DList_sort(&list); // qsort O(n*log n) + puts("sorted"); - double last = 0; - c_foreach (i, clist_fx, list) { - if (*i.ref < last) {printf("ERROR"); exit(-1);} - last = *i.ref; - } + c_forfilter (i, DList, list, c_flt_take(i, 10)) + printf("%8d: %10f\n", c_flt_last(i), *i.ref); + puts(""); - c_forfilter (i, clist_fx, list, c_flt_take(i, 10)) - printf("%8d: %10f\n", c_flt_last(i), *i.ref); - puts(""); + DList_drop(&list); + list = c_make(DList, {10, 20, 30, 40, 30, 50}); - clist_fx_clear(&list); - c_forlist (i, int, {10, 20, 30, 40, 30, 50}) - clist_fx_push_back(&list, *i.ref); + const double* v = DList_get(&list, 30); + printf("found: %f\n", *v); - const double* v = clist_fx_get(&list, 30); - printf("found: %f\n", *v); - c_foreach (i, clist_fx, list) - printf(" %g", *i.ref); - puts(""); + c_foreach (i, DList, list) + printf(" %g", *i.ref); + puts(""); - clist_fx_remove(&list, 30); - clist_fx_insert_at(&list, clist_fx_begin(&list), 5); // same as push_front() - clist_fx_push_back(&list, 500); - clist_fx_push_front(&list, 1964); + 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, clist_fx, list) - printf(" %g", *i.ref); + printf("Full: "); + c_foreach (i, DList, list) + printf(" %g", *i.ref); - printf("\nSubs: "); - clist_fx_iter it = clist_fx_begin(&list); - c_foreach (i, clist_fx, clist_fx_advance(it, 4), clist_fx_end(&list)) - printf(" %g", *i.ref); - puts(""); - } + 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 index 47f56625..0201c2d9 100644 --- a/misc/examples/list_erase.c +++ b/misc/examples/list_erase.c @@ -7,23 +7,24 @@ int main () { - c_with (IList L = c_make(IList, {10, 20, 30, 40, 50}), IList_drop(&L)) - { - 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 L = c_make(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 index f2f4946f..baebca29 100644 --- a/misc/examples/list_splice.c +++ b/misc/examples/list_splice.c @@ -16,25 +16,24 @@ void print_ilist(const char* s, clist_i list) int main () { - c_auto (clist_i, list1, list2) - { - list1 = c_make(clist_i, {1, 2, 3, 4, 5}); - list2 = c_make(clist_i, {10, 20, 30, 40, 50}); + clist_i list1 = c_make(clist_i, {1, 2, 3, 4, 5}); + clist_i list2 = c_make(clist_i, {10, 20, 30, 40, 50}); - print_ilist("list1:", list1); - print_ilist("list2:", list2); + 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); + 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); + 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)); + 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); - } + 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 index f492ccaa..6ec7544c 100644 --- a/misc/examples/lower_bound.c +++ b/misc/examples/lower_bound.c @@ -9,10 +9,9 @@ int main() { // TEST SORTED VECTOR - c_auto (cvec_int, vec) { int key, *res; - vec = c_make(cvec_int, {40, 600, 1, 7000, 2, 500, 30}); + cvec_int vec = c_make(cvec_int, {40, 600, 1, 7000, 2, 500, 30}); cvec_int_sort(&vec); @@ -35,13 +34,13 @@ int main() printf(" %d\n", *i.ref); puts(""); + cvec_int_drop(&vec); } - + // TEST SORTED SET - c_auto (csset_int, set) { int key, *res; - set = c_make(csset_int, {40, 600, 1, 7000, 2, 500, 30}); + csset_int set = c_make(csset_int, {40, 600, 1, 7000, 2, 500, 30}); key = 100; res = csset_int_lower_bound(&set, key).ref; @@ -60,5 +59,7 @@ int main() c_foreach (i, csset_int, it1, it2) printf(" %d\n", *i.ref); + + csset_int_drop(&set); } } diff --git a/misc/examples/mapmap.c b/misc/examples/mapmap.c index cad5e462..8fc307ab 100644 --- a/misc/examples/mapmap.c +++ b/misc/examples/mapmap.c @@ -44,31 +44,32 @@ int contains(Departments* map, const char* name) int main(void) { - c_auto (Departments, map) - { - add(&map, "Anna Kendro", "[email protected]", "Support"); - add(&map, "Terry Dane", "[email protected]", "Development"); - add(&map, "Kik Winston", "[email protected]", "Finance"); - add(&map, "Nancy Drew", "[email protected]", "Development"); - add(&map, "Nick Denton", "[email protected]", "Finance"); - add(&map, "Stan Whiteword", "[email protected]", "Marketing"); - add(&map, "Serena Bath", "[email protected]", "Support"); - add(&map, "Patrick Dust", "[email protected]", "Finance"); - add(&map, "Red Winger", "[email protected]", "Marketing"); - add(&map, "Nick Denton", "[email protected]", "Support"); - add(&map, "Colin Turth", "[email protected]", "Support"); - add(&map, "Dennis Kay", "[email protected]", "Marketing"); - add(&map, "Anne Dickens", "[email protected]", "Development"); + Departments map = {0}; - 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(""); + add(&map, "Anna Kendro", "[email protected]", "Support"); + add(&map, "Terry Dane", "[email protected]", "Development"); + add(&map, "Kik Winston", "[email protected]", "Finance"); + add(&map, "Nancy Drew", "[email protected]", "Development"); + add(&map, "Nick Denton", "[email protected]", "Finance"); + add(&map, "Stan Whiteword", "[email protected]", "Marketing"); + add(&map, "Serena Bath", "[email protected]", "Support"); + add(&map, "Patrick Dust", "[email protected]", "Finance"); + add(&map, "Red Winger", "[email protected]", "Marketing"); + add(&map, "Nick Denton", "[email protected]", "Support"); + add(&map, "Colin Turth", "[email protected]", "Support"); + add(&map, "Dennis Kay", "[email protected]", "Marketing"); + add(&map, "Anne Dickens", "[email protected]", "Development"); - 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"); - } + 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/mmap.c b/misc/examples/mmap.c index 3934cf26..0394a2df 100644 --- a/misc/examples/mmap.c +++ b/misc/examples/mmap.c @@ -4,14 +4,12 @@ // Multimap entries #include <stc/cstr.h> #define i_val_str -//#define i_valdrop(x) (printf("drop %s\n", cstr_str(x)), cstr_drop(x)) -#define i_extern // define _clist_mergesort() once #include <stc/clist.h> // Map of int => clist_str. #define i_type Multimap #define i_key int -#define i_valclass clist_str // uses clist_str as i_val and binds clist_str_clone, clist_str_drop +#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<int> #include <stc/csmap.h> @@ -33,40 +31,34 @@ void insert(Multimap* mmap, int key, const char* str) int main() { - c_auto (Multimap, mmap) - { - typedef struct {int a; const char* b;} pair; + Multimap mmap = {0}; - // list-initialize - 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); + // 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 value_type + insert(&mmap, 5, "pqr"); + print("#2", mmap); - // insert using make_pair - insert(&mmap, 6, "uvw"); - print("#3", mmap); + // insert using make_pair + insert(&mmap, 6, "uvw"); + print("#3", mmap); - insert(&mmap, 7, "xyz"); - print("#4", 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); + // 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_clear(&mmap); - c_forlist (i, pair, {{1, "ä"}, {2, "ё"}, {2, "ö"}, {3, "ü"}}) - insert(&mmap, i.ref->a, i.ref->b); - print("#6", 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/multimap.c b/misc/examples/multimap.c index 1b72fb67..9c37db6c 100644 --- a/misc/examples/multimap.c +++ b/misc/examples/multimap.c @@ -68,34 +68,34 @@ void OlympicLoc_drop(OlympicLoc* self) { int main() { // Define the multimap with destructor defered to when block is completed. - c_auto (csmap_OL, multimap) + csmap_OL multimap = {0}; + const clist_OL empty = clist_OL_init(); + + for (size_t i = 0; i < c_ARRAYLEN(ol_data); ++i) { - const clist_OL empty = clist_OL_init(); + 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); + } - 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); + // 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)); - } + // 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 index fcd24beb..3714e1d5 100644 --- a/misc/examples/music_arc.c +++ b/misc/examples/music_arc.c @@ -11,8 +11,6 @@ typedef struct int Song_cmp(const Song* x, const Song* y) { return cstr_cmp(&x->title, &y->title); } -uint64_t Song_hash(const Song* x) { return cstr_hash(&x->title); } - Song Song_make(const char* artist, const char* title) { return (Song){cstr_from(artist), cstr_from(title)}; } @@ -21,47 +19,45 @@ void Song_drop(Song* s) { c_drop(cstr, &s->artist, &s->title); } -// Define the reference counted type +// Define the shared pointer: #define i_type SongArc #define i_valclass Song -//#define i_opt c_no_hash +#define i_opt c_no_hash // arc require hash fn, disable as we don't need it. #include <stc/carc.h> -// ... and a vector of it +// ... and a vector of them #define i_type SongVec -#define i_valboxed SongArc +#define i_valboxed SongArc // use i_valboxed on carc / cbox instead of i_val #include <stc/cstack.h> void example3() { - c_auto (SongVec, vec1, vec2) - { - vec1 = c_make(SongVec, { - Song_make("Bob Dylan", "The Times They Are A Changing"), - Song_make("Aretha Franklin", "Bridge Over Troubled Water"), - Song_make("Thalia", "Entre El Mar y Una Estrella") - }); + SongVec vec1 = c_make(SongVec, { + Song_make("Bob Dylan", "The Times They Are A Changing"), + Song_make("Aretha Franklin", "Bridge Over Troubled Water"), + Song_make("Thalia", "Entre El Mar y Una Estrella") + }); - // 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)); + 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 - SongVec_emplace(&vec2, Song_make("Michael Jackson", "Billie Jean")); - SongVec_emplace(&vec2, Song_make("Rihanna", "Stay")); - // If we use push, we would need to construct the Arc explicitly (as in c++, make_shared): - // SongVec_push(&vec2, SongArc_from(Song_make("Rihanna", "Stay"))); + // 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); - } - } // because the shared elem. are ref. counted, they are only dropped once here. + // 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() diff --git a/misc/examples/new_deq.c b/misc/examples/new_deq.c index 39149140..467fd4e5 100644 --- a/misc/examples/new_deq.c +++ b/misc/examples/new_deq.c @@ -27,35 +27,20 @@ int point_cmp(const Point* a, const Point* b) { #define i_tag pnt #include <stc/cdeq.h> -#define i_val float -#include <stc/cdeq.h> - -#define i_val_str -#include <stc/cdeq.h> - int main() { - c_auto (cdeq_i32, vec) - { - cdeq_i32_push_back(&vec, 123); - } - c_auto (cdeq_float, fvec) - { - cdeq_float_push_back(&fvec, 123.3f); - } - c_auto (cdeq_pnt, pvec) - { - cdeq_pnt_push_back(&pvec, (Point){42, 14}); - cdeq_pnt_push_back(&pvec, (Point){32, 94}); - cdeq_pnt_push_front(&pvec, (Point){62, 81}); - cdeq_pnt_sort(&pvec); - c_foreach (i, cdeq_pnt, pvec) - printf(" (%d %d)", i.ref->x, i.ref->y); - puts(""); - } - c_auto (cdeq_str, svec) - { - cdeq_str_emplace_back(&svec, "Hello, friend"); - } + cdeq_pnt pvec = {0}; + + cdeq_pnt_push_back(&pvec, (Point){42, 14}); + cdeq_pnt_push_back(&pvec, (Point){32, 94}); + cdeq_pnt_push_front(&pvec, (Point){62, 81}); + + cdeq_pnt_sort(&pvec); + + c_foreach (i, cdeq_pnt, pvec) + printf(" (%d %d)", i.ref->x, i.ref->y); + puts(""); + + cdeq_pnt_drop(&pvec); } diff --git a/misc/examples/new_list.c b/misc/examples/new_list.c index 23709a64..eae4b8f5 100644 --- a/misc/examples/new_list.c +++ b/misc/examples/new_list.c @@ -1,19 +1,20 @@ -#include <stc/cstr.h> +#include <stdio.h> +#include <stc/forward.h> forward_clist(clist_i32, int); forward_clist(clist_pnt, struct Point); -struct MyStruct { +typedef struct { clist_i32 intlst; clist_pnt pntlst; -} typedef MyStruct; +} MyStruct; #define i_val int -#define i_opt c_is_forward #define i_tag i32 +#define i_opt c_is_forward #include <stc/clist.h> -struct Point { int x, y; } typedef Point; +typedef struct Point { int x, y; } Point; int point_cmp(const Point* a, const Point* b) { int c = a->x - b->x; return c ? c : a->y - b->y; @@ -28,34 +29,40 @@ int point_cmp(const Point* a, const Point* b) { #define i_val float #include <stc/clist.h> -#define i_val_str +void MyStruct_drop(MyStruct* s); +#define i_type MyList +#define i_valclass MyStruct // i_valclass uses MyStruct_drop +#define i_opt c_no_clone|c_no_cmp #include <stc/clist.h> +void MyStruct_drop(MyStruct* s) { + clist_i32_drop(&s->intlst); + clist_pnt_drop(&s->pntlst); +} + int main() { - c_auto (clist_i32, lst) - clist_i32_push_back(&lst, 123); - - c_auto (clist_pnt, plst) { - c_forlist (i, Point, {{42, 14}, {32, 94}, {62, 81}}) - clist_pnt_push_back(&plst, *i.ref); - - clist_pnt_sort(&plst); - - c_foreach (i, clist_pnt, plst) - printf(" (%d %d)", i.ref->x, i.ref->y); - puts(""); - } - - c_auto (clist_float, flst) { - c_forlist (i, float, {123.3f, 321.2f, -32.2f, 78.2f}) - clist_float_push_back(&flst, *i.ref); - - clist_float_sort(&flst); - c_foreach (i, clist_float, flst) printf(" %g", *i.ref); - } - - c_auto (clist_str, slst) - clist_str_emplace_back(&slst, "Hello, friend"); + MyStruct my = {0}; + clist_i32_push_back(&my.intlst, 123); + clist_pnt_push_back(&my.pntlst, (Point){123, 456}); + MyStruct_drop(&my); + + clist_pnt plst = c_make(clist_pnt, {{42, 14}, {32, 94}, {62, 81}}); + clist_pnt_sort(&plst); + + c_foreach (i, clist_pnt, plst) + printf(" (%d %d)", i.ref->x, i.ref->y); + puts(""); + clist_pnt_drop(&plst); + + + clist_float flst = c_make(clist_float, {123.3f, 321.2f, -32.2f, 78.2f}); + clist_float_sort(&flst); + + c_foreach (i, clist_float, flst) + printf(" %g", *i.ref); + + puts(""); + clist_float_drop(&flst); } diff --git a/misc/examples/new_map.c b/misc/examples/new_map.c index a4d5289c..4b02c46a 100644 --- a/misc/examples/new_map.c +++ b/misc/examples/new_map.c @@ -42,33 +42,33 @@ int point_cmp(const Point* a, const Point* b) { int main() { - c_auto (cmap_int, map) - c_auto (cmap_pnt, pmap) - c_auto (cmap_str, smap) - c_auto (cset_str, sset) - { - cmap_int_insert(&map, 123, 321); - cmap_int_insert(&map, 456, 654); - cmap_int_insert(&map, 789, 987); - - pmap = c_make(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(""); - - smap = c_make(cmap_str, { - {"Hello, friend", "long time no see"}, - {"So long", "see you around"}, - }); - - sset = c_make(cset_str, { - "Hello, friend", - "Nice to see you again", - "So long", - }); - - c_foreach (i, cset_str, sset) - printf(" %s\n", cstr_str(i.ref)); - } + cmap_pnt pmap = c_make(cmap_pnt, {{{42, 14}, 1}, {{32, 94}, 2}, {{62, 81}, 3}}); + + c_foreach (i, cmap_pnt, pmap) + printf(" (%d, %d: %d)", i.ref->first.x, i.ref->first.y, i.ref->second); + puts(""); + + cmap_str smap = c_make(cmap_str, { + {"Hello, friend", "long time no see"}, + {"So long", "see you around"}, + }); + + cset_str sset = c_make(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 index 57f27dc4..9147e3f2 100644 --- a/misc/examples/new_pque.c +++ b/misc/examples/new_pque.c @@ -10,16 +10,13 @@ struct Point { int x, y; } typedef Point; int main() { - c_auto (PointQ, pque) + PointQ pque = c_make(PointQ, {{23, 80}, {12, 32}, {54, 74}, {12, 62}}); + // print + for (; !PointQ_empty(&pque); PointQ_pop(&pque)) { - pque = c_make(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(""); + 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 index 7fae90d2..f7887ffb 100644 --- a/misc/examples/new_queue.c +++ b/misc/examples/new_queue.c @@ -25,22 +25,23 @@ int main() { stc64_t rng = stc64_new((uint64_t)time(NULL)); stc64_uniform_t dist = stc64_uniform_new(0, n); - c_auto (IQ, Q) - { - // Push 50'000'000 random numbers onto the queue. - c_forrange (n) - IQ_push(&Q, (int)stc64_uniform(&rng, &dist)); - - // Push or pop on the queue 50 million times - printf("befor: size %" c_ZI ", capacity %" c_ZI "\n", IQ_size(&Q), IQ_capacity(&Q)); - - c_forrange (n) { - int r = (int)stc64_uniform(&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 Q = {0}; + + // Push 50'000'000 random numbers onto the queue. + c_forrange (n) + IQ_push(&Q, (int)stc64_uniform(&rng, &dist)); + + // Push or pop on the queue 50 million times + printf("befor: size %" c_ZI ", capacity %" c_ZI "\n", IQ_size(&Q), IQ_capacity(&Q)); + + c_forrange (n) { + int r = (int)stc64_uniform(&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 index 0870ee3d..d85d5c75 100644 --- a/misc/examples/new_smap.c +++ b/misc/examples/new_smap.c @@ -4,15 +4,10 @@ forward_csmap(PMap, struct Point, int); // Use forward declared PMap in struct -struct MyStruct { +typedef struct { PMap pntmap; cstr name; -} typedef MyStruct; - -// int => int map -#define i_key int -#define i_val int -#include <stc/csmap.h> +} MyStruct; // Point => int map struct Point { int x, y; } typedef Point; @@ -42,36 +37,30 @@ int point_cmp(const Point* a, const Point* b) { int main() { - c_auto (csmap_int, imap) { - csmap_int_insert(&imap, 123, 321); - } - - c_auto (PMap, pmap) { - pmap = c_make(PMap, { - {{42, 14}, 1}, - {{32, 94}, 2}, - {{62, 81}, 3}, - }); + PMap pmap = c_make(PMap, { + {{42, 14}, 1}, + {{32, 94}, 2}, + {{62, 81}, 3}, + }); + SMap smap = c_make(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 (p, i, PMap, pmap) + printf(" (%d,%d: %d)", _.p->x, _.p->y, *_.i); + puts(""); - c_auto (SMap, smap) { - smap = c_make(SMap, { - {"Hello, friend", "this is the mapped value"}, - {"The brown fox", "jumped"}, - {"This is the time", "for all good things"}, - }); + c_forpair (i, j, SMap, smap) + printf(" (%s: %s)\n", cstr_str(_.i), cstr_str(_.j)); - 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"); - c_auto (SSet, sset) { - 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 index 68454970..1b72e4f5 100644 --- a/misc/examples/new_sptr.c +++ b/misc/examples/new_sptr.c @@ -31,16 +31,20 @@ uint64_t Person_hash(const Person* p); Person Person_make(const char* name, const char* last) { return (Person){.name = cstr_from(name), .last = cstr_from(last)}; } + 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); @@ -48,26 +52,24 @@ void Person_drop(Person* p) { int main(void) { - c_auto (PersonArc, p, q, r, s) - { - puts("Ex1"); - p = PersonArc_from(Person_make("John", "Smiths")); - q = PersonArc_clone(p); // share - r = PersonArc_clone(p); - 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_auto (IPStack, vec) - { - puts("Ex2"); - 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))); + 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(""); - } + 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 index 84e4c7b2..988b78d9 100644 --- a/misc/examples/new_vec.c +++ b/misc/examples/new_vec.c @@ -1,4 +1,4 @@ -#include <stc/cstr.h> +#include <stdio.h> #include <stc/forward.h> forward_cvec(cvec_i32, int); @@ -14,45 +14,29 @@ struct MyStruct { #define i_tag i32 #include <stc/cvec.h> -struct Point { int x, y; } typedef 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); -} +typedef struct Point { int x, y; } Point; #define i_val Point -//#define i_cmp point_cmp #define i_less(a, b) a->x < b->x || (a->x == b->x && a->y < b->y) #define i_opt c_is_forward #define i_tag pnt #include <stc/cvec.h> -#define i_val float -#include <stc/cvec.h> +int main() +{ + MyStruct my = {0}; -#define i_val_str -#include <stc/cvec.h> + cvec_pnt_push(&my.pntvec, (Point){42, 14}); + cvec_pnt_push(&my.pntvec, (Point){32, 94}); + cvec_pnt_push(&my.pntvec, (Point){62, 81}); + cvec_pnt_push(&my.pntvec, (Point){32, 91}); + cvec_pnt_sort(&my.pntvec); -int main() -{ - c_auto (cvec_i32, vec) - c_auto (cvec_float, fvec) - c_auto (cvec_pnt, pvec) - c_auto (cvec_str, svec) - { - cvec_i32_push(&vec, 123); - cvec_float_push(&fvec, 123.3f); - - cvec_pnt_push(&pvec, (Point){42, 14}); - cvec_pnt_push(&pvec, (Point){32, 94}); - cvec_pnt_push(&pvec, (Point){62, 81}); - cvec_pnt_push(&pvec, (Point){32, 91}); - cvec_pnt_sort(&pvec); - c_foreach (i, cvec_pnt, pvec) - printf(" (%d %d)", i.ref->x, i.ref->y); - puts(""); - - cvec_str_emplace(&svec, "Hello, friend"); - } + 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 index a7bf2a6f..620d311f 100644 --- a/misc/examples/person_arc.c +++ b/misc/examples/person_arc.c @@ -39,13 +39,15 @@ void Person_drop(Person* p) { int main() { - c_auto (Persons, vec) - c_auto (PSPtr, p, q) - { - p = PSPtr_from(Person_make("Laura", "Palmer")); - - // We want a deep copy -- PSPtr_clone(p) only shares! - q = PSPtr_from(Person_clone(*p.get)); + 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)); @@ -65,10 +67,9 @@ int main() puts(""); // Look-up Audrey! - c_with (Person a = Person_make("Audrey", "Home"), Person_drop(&a)) { - const PSPtr *v = Persons_get(&vec, a); - if (v) printf("found: %s %s\n", cstr_str(&v->get->name), cstr_str(&v->get->last)); - } - puts(""); + 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 index ec9c5876..c0007cb7 100644 --- a/misc/examples/phonebook.c +++ b/misc/examples/phonebook.c @@ -38,37 +38,35 @@ void print_phone_book(cmap_str phone_book) int main(int argc, char **argv) { - c_auto (cmap_str, phone_book) - { - phone_book = c_make(cmap_str, { - {"Lilia Friedman", "(892) 670-4739"}, - {"Tariq Beltran", "(489) 600-7575"}, - {"Laiba Juarez", "(303) 885-5692"}, - {"Elliott Mooney", "(945) 616-4482"}, - }); + cmap_str phone_book = c_make(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); + 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_contains(&phone_book, "Tariq Beltran")) - printf("\nTariq Beltran is in phone book\n"); + 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"); + 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); + 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); - } - puts("done"); + 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 index 16a59774..18bf3490 100644 --- a/misc/examples/prime.c +++ b/misc/examples/prime.c @@ -30,24 +30,25 @@ int main(void) printf("Computing prime numbers up to %" c_ZI "\n", n); clock_t t1 = clock(); - c_with (cbits primes = sieveOfEratosthenes(n + 1), cbits_drop(&primes)) { - int64_t np = cbits_count(&primes); - clock_t t2 = clock(); + cbits primes = sieveOfEratosthenes(n + 1); + int64_t np = cbits_count(&primes); + clock_t t2 = clock(); - printf("Number of primes: %" c_ZI ", time: %f\n\n", np, (float)(t2 - t1) / (float)CLOCKS_PER_SEC); - 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"); + printf("Number of primes: %" c_ZI ", time: %f\n\n", np, (float)(t2 - t1) / (float)CLOCKS_PER_SEC); + 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 R = crange_make(n - 1, 0, -2); - c_forfilter (i, crange, R, - cbits_test(&primes, *i.ref>>1) && - c_flt_take(i, 50)) { - printf("%lld ", *i.ref); - if (c_flt_last(i) % 10 == 0) puts(""); - } + puts("Show the last 50 primes using a temporary crange generator:"); + crange R = crange_make(n - 1, 0, -2); + c_forfilter (i, crange, R, + cbits_test(&primes, *i.ref>>1) && + c_flt_take(i, 50)) { + printf("%lld ", *i.ref); + if (c_flt_last(i) % 10 == 0) puts(""); } + + cbits_drop(&primes); } diff --git a/misc/examples/printspan.c b/misc/examples/printspan.c index 81f6fa14..127b07b9 100644 --- a/misc/examples/printspan.c +++ b/misc/examples/printspan.c @@ -22,22 +22,26 @@ void printMe(intspan container) { int main() { - c_auto (cvec_int, vec) - c_auto (cstack_int, stk) - c_auto (cdeq_int, deq) - c_auto (csset_str, set) - { - intspan sp1 = cspan_make(intspan, {1, 2}); - printMe( sp1 ); - - printMe( c_make(intspan, {1, 2, 3}) ); - - int arr[] = {1, 2, 3, 4, 5, 6}; - intspan sp2 = cspan_from_array(arr); - printMe( (intspan)cspan_subspan(&sp2, 1, 4) ); - - c_forlist (i, int, {1, 2, 3, 4, 5}) - cvec_int_push(&vec, *i.ref); + intspan sp1 = cspan_make(intspan, {1, 2}); + printMe( sp1 ); + + printMe( c_make(intspan, {1, 2, 3}) ); + + int arr[] = {1, 2, 3, 4, 5, 6}; + intspan sp2 = cspan_from_array(arr); + printMe( (intspan)cspan_subspan(&sp2, 1, 4) ); + + cvec_int vec; + cstack_int stk; + cdeq_int deq; + csset_str set; + c_defer( + cvec_int_drop(&vec), + cstack_int_drop(&stk), + cdeq_int_drop(&deq), + csset_str_drop(&set) + ) { + vec = c_make(cvec_int, {1, 2, 3, 4, 5}); printMe( (intspan)cspan_from(&vec) ); printMe( sp2 ); diff --git a/misc/examples/priority.c b/misc/examples/priority.c index 0a1d419b..d3d0283e 100644 --- a/misc/examples/priority.c +++ b/misc/examples/priority.c @@ -12,24 +12,26 @@ int main() { intptr_t N = 10000000; stc64_t rng = stc64_new((uint64_t)time(NULL)); stc64_uniform_t dist = stc64_uniform_new(0, N * 10); - c_auto (cpque_i, heap) - { - // Push ten million random numbers to priority queue - printf("Push %" c_ZI " numbers\n", N); - c_forrange (N) - cpque_i_push(&heap, stc64_uniform(&rng, &dist)); - - // push some negative numbers too. - c_forlist (i, int, {-231, -32, -873, -4, -343}) - cpque_i_push(&heap, *i.ref); - - c_forrange (N) - cpque_i_push(&heap, stc64_uniform(&rng, &dist)); - - puts("Extract the hundred smallest."); - c_forrange (100) { - printf("%" PRId64 " ", *cpque_i_top(&heap)); - cpque_i_pop(&heap); - } + + 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, stc64_uniform(&rng, &dist)); + + // push some negative numbers too. + c_forlist (i, int, {-231, -32, -873, -4, -343}) + cpque_i_push(&heap, *i.ref); + + c_forrange (N) + cpque_i_push(&heap, stc64_uniform(&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 index 4064cc77..0f387d52 100644 --- a/misc/examples/queue.c +++ b/misc/examples/queue.c @@ -11,21 +11,22 @@ int main() { stc64_t rng = stc64_new(1234); dist = stc64_uniform_new(0, n); - c_auto (cqueue_i, queue) - { - // Push ten million random numbers onto the queue. - c_forrange (n) - cqueue_i_push(&queue, (int)stc64_uniform(&rng, &dist)); + cqueue_i queue = {0}; - // Push or pop on the queue ten million times - printf("%d\n", n); - c_forrange (n) { // forrange uses initial n only. - int r = (int)stc64_uniform(&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)); + // Push ten million random numbers onto the queue. + c_forrange (n) + cqueue_i_push(&queue, (int)stc64_uniform(&rng, &dist)); + + // Push or pop on the queue ten million times + printf("%d\n", n); + c_forrange (n) { // forrange uses initial n only. + int r = (int)stc64_uniform(&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/rawptr_elements.c b/misc/examples/rawptr_elements.c index 4b3d2056..f46a7f5e 100644 --- a/misc/examples/rawptr_elements.c +++ b/misc/examples/rawptr_elements.c @@ -28,9 +28,13 @@ typedef int64_t inttype; int main() { - c_auto (SIPtrMap, map, m1) - c_auto (SIBoxMap, m2) - { + SIPtrMap map = {0}, m1; + SIBoxMap m2 = {0}; + c_defer( + SIPtrMap_drop(&map), + SIPtrMap_drop(&m1), + SIBoxMap_drop(&m2) + ){ printf("\nMap with pointer elements:\n"); SIPtrMap_insert(&map, cstr_from("testing"), c_new(inttype, 1)); SIPtrMap_insert(&map, cstr_from("done"), c_new(inttype, 2)); diff --git a/misc/examples/regex1.c b/misc/examples/regex1.c index c311e455..4a56b8ac 100644 --- a/misc/examples/regex1.c +++ b/misc/examples/regex1.c @@ -7,24 +7,26 @@ int main(int argc, char* argv[]) printf("Usage: regex1 -i\n"); return 0; } - c_auto (cstr, input) - c_auto (cregex, float_expr) + 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) { - 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); + 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; + // 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"); - } + 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 index 20bd323c..883dd112 100644 --- a/misc/examples/regex2.c +++ b/misc/examples/regex2.c @@ -15,7 +15,7 @@ int main() {"\\p{Han}+", "This is Han: 王明:那是杂志吗?"}, }; - c_auto (cregex, re) + cregex re = {0}; c_forrange (i, c_ARRAYLEN(s)) { int res = cregex_compile(&re, s[i].pattern); @@ -30,4 +30,5 @@ int main() 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 index dcc19c1f..def0ae7a 100644 --- a/misc/examples/regex_match.c +++ b/misc/examples/regex_match.c @@ -12,24 +12,25 @@ int main() " 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}; - c_auto (cregex, re) - c_auto (cstack_float, vec) - c_auto (cstr, nums) - { - const char* pattern = "[+-]?([0-9]*\\.)?\\d+([Ee][+-]?\\d+)?"; - int res = cregex_compile(&re, pattern); - printf("%d: %s\n", res, pattern); + 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)); + // 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", *i.ref); + c_foreach (i, cstack_float, vec) + printf(" %g\n", *i.ref); - // extracts the numbers only to a comma separated string. - nums = cregex_replace_sv(&re, csview_from(str), " $0,", 0, NULL, CREG_R_STRIP); - printf("\n%s\n", cstr_str(&nums)); - } + // extracts the numbers only to a comma separated string. + cstr nums = cregex_replace_sv(&re, csview_from(str), " $0,", 0, NULL, CREG_R_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 index ebb57488..d3952f50 100644 --- a/misc/examples/regex_replace.c +++ b/misc/examples/regex_replace.c @@ -16,9 +16,13 @@ int main() { 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_auto (cstr, str) - { + c_defer( + cregex_drop(&re), + cstr_drop(&str) + ){ printf("INPUT: %s\n", input); /* replace with a fixed string, extended all-in-one call: */ @@ -34,17 +38,17 @@ int main() printf("brack: %s\n", cstr_str(&str)); /* Shows how to compile RE separately */ - c_with (cregex re = cregex_from(pattern), cregex_drop(&re)) { - if (cregex_captures(&re) == 0) - continue; /* break c_with */ - /* 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_R_STRIP)); - printf("strip: %s\n", cstr_str(&str)); - } + 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_R_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}")); diff --git a/misc/examples/shape.c b/misc/examples/shape.c index d290fb4d..2aabdcc2 100644 --- a/misc/examples/shape.c +++ b/misc/examples/shape.c @@ -138,7 +138,8 @@ void testShape(const Shape* shape) int main(void) { - c_auto (Shapes, shapes) + Shapes shapes = {0}; + c_defer (Shapes_drop(&shapes)) { Triangle* tri1 = c_new(Triangle, Triangle_from((Point){5, 7}, (Point){12, 7}, (Point){12, 20})); Polygon* pol1 = c_new(Polygon, Polygon_init()); diff --git a/misc/examples/sidebyside.cpp b/misc/examples/sidebyside.cpp index 80c934a4..a817b5a5 100644 --- a/misc/examples/sidebyside.cpp +++ b/misc/examples/sidebyside.cpp @@ -25,8 +25,8 @@ int main() { std::cout << std::endl; } - c_auto (IIMap, hist) - { + IIMap hist = {0}; + c_defer (IIMap_drop(&hist)) { IIMap_insert(&hist, 12, 100).ref->second += 1; IIMap_insert(&hist, 13, 100).ref->second += 1; IIMap_insert(&hist, 12, 100).ref->second += 1; @@ -45,10 +45,11 @@ int main() { std::cout << std::endl; } - c_auto (SIMap, food) + SIMap food = {0}; + c_defer (SIMap_drop(&food)) { c_forlist (i, SIMap_raw, {{"burger", 5}, {"pizza", 12}, {"steak", 15}}) - SIMap_emplace(&food, c_PAIR(i.ref)); + 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); diff --git a/misc/examples/sorted_map.c b/misc/examples/sorted_map.c index c4a05c76..ae9b45a4 100644 --- a/misc/examples/sorted_map.c +++ b/misc/examples/sorted_map.c @@ -9,8 +9,11 @@ int main() { // empty map containers - c_auto (csmap_int, gquiz1, gquiz2) - { + 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); diff --git a/misc/examples/sso_map.c b/misc/examples/sso_map.c index 128cf50d..70450e21 100644 --- a/misc/examples/sso_map.c +++ b/misc/examples/sso_map.c @@ -5,13 +5,14 @@ int main() { - c_auto (cmap_str, m) { - cmap_str_emplace(&m, "Test short", "This is a short string"); - cmap_str_emplace(&m, "Test long ", "This is a longer string"); + 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"); - } + 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/stack.c b/misc/examples/stack.c index 50dc8eb7..c817e1ae 100644 --- a/misc/examples/stack.c +++ b/misc/examples/stack.c @@ -11,20 +11,22 @@ #include <stc/cstack.h> int main() { - c_auto (cstack_i, stack) - c_auto (cstack_c, chars) - { - 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 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/sview_split.c b/misc/examples/sview_split.c index 18d547f8..31a28e51 100644 --- a/misc/examples/sview_split.c +++ b/misc/examples/sview_split.c @@ -12,8 +12,7 @@ int main() printf("%.*s, %.*s, %.*s\n", c_SV(year), c_SV(month), c_SV(day)); - c_auto (cstr, y, m, d) { - 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)); - } + 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/unordered_set.c b/misc/examples/unordered_set.c index f9221b21..61f9cc1f 100644 --- a/misc/examples/unordered_set.c +++ b/misc/examples/unordered_set.c @@ -7,8 +7,10 @@ int main() { // declaring set for storing string data-type - c_auto (cset_str, stringSet) - { + 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"); diff --git a/misc/examples/utf8replace_c.c b/misc/examples/utf8replace_c.c index b697efd8..3cde8701 100644 --- a/misc/examples/utf8replace_c.c +++ b/misc/examples/utf8replace_c.c @@ -2,24 +2,23 @@ int main() { - c_auto (cstr, hello, str) - { - hello = cstr_lit("hell😀 w😀rld"); - printf("%s\n", cstr_str(&hello)); + 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)); + /* 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)); - - str = cstr_lit("scooby, dooby doo"); - cstr_replace(&str, "oo", "00"); - printf("\n%s\n", cstr_str(&str)); - } + 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/vikings.c b/misc/examples/vikings.c index 7a21d0a5..abb909c3 100644 --- a/misc/examples/vikings.c +++ b/misc/examples/vikings.c @@ -39,28 +39,20 @@ static inline RViking Viking_toraw(const Viking* vp) { #define i_hash(rp) cstrhash(rp->name) ^ cstrhash(rp->country) #define i_val int // mapped type #include <stc/cmap.h> -/* - i_keyclass implies these defines, unless they are already defined: - i_cmp => RViking_cmp - //i_hash => RViking_hash // already defined. - //i_keyclone => Viking_clone // not used, because of c_no_clone - i_keyto => Viking_toraw // because i_rawclass is defined - i_keydrop => Viking_drop -*/ int main() { - c_auto (Vikings, vikings) { - Vikings_emplace(&vikings, (RViking){"Einar", "Norway"}, 20); - Vikings_emplace(&vikings, (RViking){"Olaf", "Denmark"}, 24); - Vikings_emplace(&vikings, (RViking){"Harald", "Iceland"}, 12); - Vikings_emplace(&vikings, (RViking){"Björn", "Sweden"}, 10); + Vikings vikings = {0}; + Vikings_emplace(&vikings, (RViking){"Einar", "Norway"}, 20); + Vikings_emplace(&vikings, (RViking){"Olaf", "Denmark"}, 24); + Vikings_emplace(&vikings, (RViking){"Harald", "Iceland"}, 12); + Vikings_emplace(&vikings, (RViking){"Björn", "Sweden"}, 10); - Vikings_value* v = Vikings_get_mut(&vikings, (RViking){"Einar", "Norway"}); - v->second += 3; // add 3 hp points to Einar + Vikings_value* v = Vikings_get_mut(&vikings, (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); - } + 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/words.c b/misc/examples/words.c deleted file mode 100644 index f097a991..00000000 --- a/misc/examples/words.c +++ /dev/null @@ -1,68 +0,0 @@ -#include <math.h> -#include <stc/cstr.h> - -#define i_val_str -#include <stc/cvec.h> - -#define i_key_str -#define i_val int -#include <stc/cmap.h> - -int main1() -{ - c_auto (cvec_str, words) - c_auto (cmap_str, word_map) - { - words = c_make(cvec_str, { - "this", "sentence", "is", "not", "a", "sentence", - "this", "sentence", "is", "a", "hoax" - }); - - c_foreach (w, cvec_str, words) { - cmap_str_emplace(&word_map, cstr_str(w.ref), 0).ref->second += 1; - } - - c_foreach (i, cmap_str, word_map) { - printf("%d occurrences of word '%s'\n", - i.ref->second, cstr_str(&i.ref->first)); - } - } - return 0; -} - -#ifdef __cplusplus -#include <string> -#include <iostream> -#include <vector> -#include <unordered_map> - -int main2() -{ - std::vector<std::string> words = { - "this", "sentence", "is", "not", "a", "sentence", - "this", "sentence", "is", "a", "hoax" - }; - - std::unordered_map<std::string, size_t> word_map; - for (const auto &w : words) { - word_map[w] += 1; - } - - for (const auto &pair : word_map) { - std::cout << pair.second - << " occurrences of word '" - << pair.first << "'\n"; - } - return 0; -} - -int main() { - main1(); - puts(""); - main2(); -} -#else -int main() { - main1(); -} -#endif |
