summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--README.md169
-rw-r--r--docs/carc_api.md96
-rw-r--r--docs/cbox_api.md11
-rw-r--r--docs/ccommon_api.md195
-rw-r--r--docs/clist_api.md23
-rw-r--r--docs/cmap_api.md191
-rw-r--r--docs/coption_api.md2
-rw-r--r--docs/cpque_api.md34
-rw-r--r--docs/cset_api.md50
-rw-r--r--docs/csmap_api.md109
-rw-r--r--docs/cspan_api.md19
-rw-r--r--docs/csset_api.md49
-rw-r--r--docs/cstr_api.md7
-rw-r--r--docs/csview_api.md28
-rw-r--r--docs/cvec_api.md46
-rw-r--r--include/c11/print.h (renamed from include/c11/fmt.h)2
-rw-r--r--include/stc/ccommon.h29
-rw-r--r--include/stc/priv/raii.h27
-rw-r--r--misc/benchmarks/various/rust_cmap.c68
-rw-r--r--misc/examples/arc_containers.c11
-rw-r--r--misc/examples/arc_demo.c65
-rw-r--r--misc/examples/arcvec_erase.c66
-rw-r--r--misc/examples/astar.c45
-rw-r--r--misc/examples/birthday.c44
-rw-r--r--misc/examples/bits.c51
-rw-r--r--misc/examples/books.c6
-rw-r--r--misc/examples/box.c46
-rw-r--r--misc/examples/box2.c34
-rw-r--r--misc/examples/city.c92
-rw-r--r--misc/examples/complex.c37
-rw-r--r--misc/examples/convert.c15
-rw-r--r--misc/examples/csmap_erase.c113
-rw-r--r--misc/examples/csmap_find.c46
-rw-r--r--misc/examples/csmap_insert.c134
-rw-r--r--misc/examples/csset_erase.c69
-rw-r--r--misc/examples/cstr_match.c32
-rw-r--r--misc/examples/demos.c196
-rw-r--r--misc/examples/forfilter.c129
-rw-r--r--misc/examples/forloops.c82
-rw-r--r--misc/examples/functor.c23
-rw-r--r--misc/examples/gauss1.c40
-rw-r--r--misc/examples/gauss2.c29
-rw-r--r--misc/examples/hashmap.c55
-rw-r--r--misc/examples/inits.c112
-rw-r--r--misc/examples/intrusive.c63
-rw-r--r--misc/examples/list.c91
-rw-r--r--misc/examples/list_erase.c39
-rw-r--r--misc/examples/list_splice.c31
-rw-r--r--misc/examples/lower_bound.c11
-rw-r--r--misc/examples/mapmap.c51
-rw-r--r--misc/examples/mmap.c58
-rw-r--r--misc/examples/multimap.c52
-rw-r--r--misc/examples/music_arc.c58
-rw-r--r--misc/examples/new_deq.c41
-rw-r--r--misc/examples/new_list.c67
-rw-r--r--misc/examples/new_map.c58
-rw-r--r--misc/examples/new_pque.c17
-rw-r--r--misc/examples/new_queue.c35
-rw-r--r--misc/examples/new_smap.c59
-rw-r--r--misc/examples/new_sptr.c44
-rw-r--r--misc/examples/new_vec.c48
-rw-r--r--misc/examples/person_arc.c25
-rw-r--r--misc/examples/phonebook.c48
-rw-r--r--misc/examples/prime.c35
-rw-r--r--misc/examples/printspan.c36
-rw-r--r--misc/examples/priority.c40
-rw-r--r--misc/examples/queue.c31
-rw-r--r--misc/examples/rawptr_elements.c10
-rw-r--r--misc/examples/regex1.c34
-rw-r--r--misc/examples/regex2.c3
-rw-r--r--misc/examples/regex_match.c33
-rw-r--r--misc/examples/regex_replace.c30
-rw-r--r--misc/examples/shape.c3
-rw-r--r--misc/examples/sidebyside.cpp9
-rw-r--r--misc/examples/sorted_map.c7
-rw-r--r--misc/examples/sso_map.c17
-rw-r--r--misc/examples/stack.c34
-rw-r--r--misc/examples/sview_split.c7
-rw-r--r--misc/examples/unordered_set.c6
-rw-r--r--misc/examples/utf8replace_c.c35
-rw-r--r--misc/examples/vikings.c28
-rw-r--r--misc/examples/words.c68
82 files changed, 1954 insertions, 2135 deletions
diff --git a/README.md b/README.md
index cfab70ad..8d816bc6 100644
--- a/README.md
+++ b/README.md
@@ -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(&current, &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