diff options
| author | Tyge Løvset <[email protected]> | 2022-06-01 16:28:07 +0200 |
|---|---|---|
| committer | Tyge Løvset <[email protected]> | 2022-06-01 16:28:07 +0200 |
| commit | de629774cb912aa3d563f24d99258142713c3fcd (patch) | |
| tree | c37e2851d6cb049bc0863a59b6ecf5945fb88619 /examples | |
| parent | 7fb43a24a17da787dd809114ca26c1231b058493 (diff) | |
| download | STC-modified-de629774cb912aa3d563f24d99258142713c3fcd.tar.gz STC-modified-de629774cb912aa3d563f24d99258142713c3fcd.zip | |
Converted all files with DOS line endings to LINUX.
Diffstat (limited to 'examples')
53 files changed, 3445 insertions, 3445 deletions
diff --git a/examples/README.md b/examples/README.md index ad7726d4..4c0aa763 100644 --- a/examples/README.md +++ b/examples/README.md @@ -1,4 +1,4 @@ -Examples
-========
-This folder contains various examples of STC container usage.
-
+Examples +======== +This folder contains various examples of STC container usage. + diff --git a/examples/arc_containers.c b/examples/arc_containers.c index 1fe227f7..969825eb 100644 --- a/examples/arc_containers.c +++ b/examples/arc_containers.c @@ -1,77 +1,77 @@ -// Create a stack and a list of shared pointers to maps,
-// and demonstrate sharing and cloning of maps.
-#define i_static
-#include <stc/cstr.h>
-#define i_type Map
-#define i_key_str // strings
-#define i_val int
-#define i_keydrop(p) (printf("drop name: %s\n", cstr_str(p)), cstr_drop(p))
-#include <stc/csmap.h>
-
-#define i_type Arc // (atomic) ref. counted type
-#define i_val Map
-#define i_valdrop(p) (printf("drop Arc:\n"), Map_drop(p))
-// no need for atomic ref. count in single thread:
-// no compare function available for csmap:
-#define i_opt c_no_atomic|c_no_cmp
-#include <stc/carc.h>
-
-#define i_type Stack
-#define i_val_arcbox Arc // define i_val_bind for carc/cbox value (not i_val)
-#include <stc/cstack.h>
-
-#define i_type List
-#define i_val_arcbox Arc // as above
-#include <stc/clist.h>
-
-int main()
-{
- c_auto (Stack, stack)
- c_auto (List, list)
- {
- // POPULATE stack with shared pointers to Maps:
- Map *map;
- map = Stack_push(&stack, Arc_make(Map_init()))->get;
- c_apply(v, Map_emplace(map, c_pair(v)), Map_raw, {
- {"Joey", 1990}, {"Mary", 1995}, {"Joanna", 1992}
- });
- map = Stack_push(&stack, Arc_make(Map_init()))->get;
- c_apply(v, Map_emplace(map, c_pair(v)), Map_raw, {
- {"Rosanna", 2001}, {"Brad", 1999}, {"Jack", 1980}
- });
-
- // POPULATE list:
- map = List_push_back(&list, Arc_make(Map_init()))->get;
- c_apply(v, Map_emplace(map, c_pair(v)), Map_raw, {
- {"Steve", 1979}, {"Rick", 1974}, {"Tracy", 2003}
- });
-
- // Share two Maps from the stack with the list using emplace (clone the carc):
- List_push_back(&list, Arc_clone(stack.data[0]));
- List_push_back(&list, Arc_clone(stack.data[1]));
-
- // Clone (deep copy) a Map from the stack to the list
- // List will contain two shared and two unshared maps.
- map = List_push_back(&list, Arc_make(Map_clone(*stack.data[1].get)))->get;
-
- // Add one more element to the cloned map:
- Map_emplace_or_assign(map, "CLONED", 2021);
-
- // Add one more element to the shared map:
- Map_emplace_or_assign(stack.data[1].get, "SHARED", 2021);
-
-
- puts("STACKS");
- c_foreach (i, Stack, stack) {
- c_forpair (name, year, Map, *i.ref->get)
- printf(" %s:%d", cstr_str(_.name), *_.year);
- puts("");
- }
- puts("LIST");
- c_foreach (i, List, list) {
- c_forpair (name, year, Map, *i.ref->get)
- printf(" %s:%d", cstr_str(_.name), *_.year);
- puts("");
- }
- }
-}
+// Create a stack and a list of shared pointers to maps, +// and demonstrate sharing and cloning of maps. +#define i_static +#include <stc/cstr.h> +#define i_type Map +#define i_key_str // strings +#define i_val int +#define i_keydrop(p) (printf("drop name: %s\n", cstr_str(p)), cstr_drop(p)) +#include <stc/csmap.h> + +#define i_type Arc // (atomic) ref. counted type +#define i_val Map +#define i_valdrop(p) (printf("drop Arc:\n"), Map_drop(p)) +// no need for atomic ref. count in single thread: +// no compare function available for csmap: +#define i_opt c_no_atomic|c_no_cmp +#include <stc/carc.h> + +#define i_type Stack +#define i_val_arcbox Arc // define i_val_bind for carc/cbox value (not i_val) +#include <stc/cstack.h> + +#define i_type List +#define i_val_arcbox Arc // as above +#include <stc/clist.h> + +int main() +{ + c_auto (Stack, stack) + c_auto (List, list) + { + // POPULATE stack with shared pointers to Maps: + Map *map; + map = Stack_push(&stack, Arc_make(Map_init()))->get; + c_apply(v, Map_emplace(map, c_pair(v)), Map_raw, { + {"Joey", 1990}, {"Mary", 1995}, {"Joanna", 1992} + }); + map = Stack_push(&stack, Arc_make(Map_init()))->get; + c_apply(v, Map_emplace(map, c_pair(v)), Map_raw, { + {"Rosanna", 2001}, {"Brad", 1999}, {"Jack", 1980} + }); + + // POPULATE list: + map = List_push_back(&list, Arc_make(Map_init()))->get; + c_apply(v, Map_emplace(map, c_pair(v)), Map_raw, { + {"Steve", 1979}, {"Rick", 1974}, {"Tracy", 2003} + }); + + // Share two Maps from the stack with the list using emplace (clone the carc): + List_push_back(&list, Arc_clone(stack.data[0])); + List_push_back(&list, Arc_clone(stack.data[1])); + + // Clone (deep copy) a Map from the stack to the list + // List will contain two shared and two unshared maps. + map = List_push_back(&list, Arc_make(Map_clone(*stack.data[1].get)))->get; + + // Add one more element to the cloned map: + Map_emplace_or_assign(map, "CLONED", 2021); + + // Add one more element to the shared map: + Map_emplace_or_assign(stack.data[1].get, "SHARED", 2021); + + + puts("STACKS"); + c_foreach (i, Stack, stack) { + c_forpair (name, year, Map, *i.ref->get) + printf(" %s:%d", cstr_str(_.name), *_.year); + puts(""); + } + puts("LIST"); + c_foreach (i, List, list) { + c_forpair (name, year, Map, *i.ref->get) + printf(" %s:%d", cstr_str(_.name), *_.year); + puts(""); + } + } +} diff --git a/examples/arc_demo.c b/examples/arc_demo.c index daeb5a68..85e3886f 100644 --- a/examples/arc_demo.c +++ b/examples/arc_demo.c @@ -1,56 +1,56 @@ -#include <stdio.h>
-#include <string.h>
-
-void int_drop(int* x) {
- printf("drop: %d\n", *x);
-}
-
-// carc implements its own clone method using reference counting,
-// so 'i_valclone' is not required to be defined (ignored).
-
-#define i_type Arc // set type name to be defined (instead of 'carc_int')
-#define i_val int
-#define i_valdrop int_drop // optional, just to display the elements destroyed
-#include <stc/carc.h> // Arc
-
-#define i_key_arcbox Arc // note: use i_key_bind instead of i_key for carc/cbox elements
-#include <stc/csset.h> // csset_Arc (like: std::set<std::shared_ptr<int>>)
-
-#define i_val_arcbox Arc // note: as above.
-#include <stc/cvec.h> // cvec_Arc (like: std::vector<std::shared_ptr<int>>)
-
-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_back(&vec, Arc_make(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_autovar (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");
- }
-}
+#include <stdio.h> +#include <string.h> + +void int_drop(int* x) { + printf("drop: %d\n", *x); +} + +// carc implements its own clone method using reference counting, +// so 'i_valclone' is not required to be defined (ignored). + +#define i_type Arc // set type name to be defined (instead of 'carc_int') +#define i_val int +#define i_valdrop int_drop // optional, just to display the elements destroyed +#include <stc/carc.h> // Arc + +#define i_key_arcbox Arc // note: use i_key_bind instead of i_key for carc/cbox elements +#include <stc/csset.h> // csset_Arc (like: std::set<std::shared_ptr<int>>) + +#define i_val_arcbox Arc // note: as above. +#include <stc/cvec.h> // cvec_Arc (like: std::vector<std::shared_ptr<int>>) + +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_back(&vec, Arc_make(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_autovar (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"); + } +} diff --git a/examples/arcvec_erase.c b/examples/arcvec_erase.c index e4497486..eba77f51 100644 --- a/examples/arcvec_erase.c +++ b/examples/arcvec_erase.c @@ -1,53 +1,53 @@ -#include <stdio.h>
-
-void show_drop(int* x) { printf("drop: %d\n", *x); }
-
-#define i_type Arc
-#define i_val int
-#define i_valdrop show_drop
-// carc/cbox will use pointer address comparison of i_val
-// if 'i_opt c_no_cmp' is defined, otherwise i_cmp is used
-// to compare object values. See the two differences by
-// commenting out the next line.
-#include <stc/carc.h> // Shared pointer to int
-
-#define i_type Vec
-#define i_val_arcbox Arc
-#include <stc/cvec.h> // Vec: cvec<Arc>
-
-
-int main()
-{
- c_auto (Vec, vec)
- {
- const int v[] = {2012, 1990, 2012, 2019, 2015};
- c_forrange (i, c_arraylen(v))
- Vec_push_back(&vec, Arc_make(v[i]));
-
- // clone the second 2012 and push it back.
- // note: cloning make sure that vec.data[2] has ref count 2.
- Vec_push_back(&vec, Arc_clone(vec.data[2]));
-
- printf("vec before erase :");
- c_foreach (i, Vec, vec)
- printf(" %d", *i.ref->get);
- puts("");
-
- printf("erase 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_end(&vec).ref)
- Vec_erase_at(&vec, it);
-
- int year = 2015;
- it = Vec_find(&vec, year); // Ok as tmp only.
- if (it.ref != Vec_end(&vec).ref)
- Vec_erase_at(&vec, it);
-
- printf("vec after erase :");
- c_foreach (i, Vec, vec)
- printf(" %d", *i.ref->get);
-
- puts("\nDone");
- }
-}
+#include <stdio.h> + +void show_drop(int* x) { printf("drop: %d\n", *x); } + +#define i_type Arc +#define i_val int +#define i_valdrop show_drop +// carc/cbox will use pointer address comparison of i_val +// if 'i_opt c_no_cmp' is defined, otherwise i_cmp is used +// to compare object values. See the two differences by +// commenting out the next line. +#include <stc/carc.h> // Shared pointer to int + +#define i_type Vec +#define i_val_arcbox Arc +#include <stc/cvec.h> // Vec: cvec<Arc> + + +int main() +{ + c_auto (Vec, vec) + { + const int v[] = {2012, 1990, 2012, 2019, 2015}; + c_forrange (i, c_arraylen(v)) + Vec_push_back(&vec, Arc_make(v[i])); + + // clone the second 2012 and push it back. + // note: cloning make sure that vec.data[2] has ref count 2. + Vec_push_back(&vec, Arc_clone(vec.data[2])); + + printf("vec before erase :"); + c_foreach (i, Vec, vec) + printf(" %d", *i.ref->get); + puts(""); + + printf("erase 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_end(&vec).ref) + Vec_erase_at(&vec, it); + + int year = 2015; + it = Vec_find(&vec, year); // Ok as tmp only. + if (it.ref != Vec_end(&vec).ref) + Vec_erase_at(&vec, it); + + printf("vec after erase :"); + c_foreach (i, Vec, vec) + printf(" %d", *i.ref->get); + + puts("\nDone"); + } +} diff --git a/examples/astar.c b/examples/astar.c index 5bcbe7e9..db2d128c 100644 --- a/examples/astar.c +++ b/examples/astar.c @@ -1,167 +1,167 @@ -//
-// -- An A* pathfinder inspired by the excellent tutorial at Red Blob Games --
-//
-// This is a reimplementation of the CTL example to STC:
-// https://github.com/glouw/ctl/blob/master/examples/astar.c
-// https://www.redblobgames.com/pathfinding/a-star/introduction.html
-#define i_implement
-#include <stc/cstr.h>
-#include <stdio.h>
-
-typedef struct
-{
- int x;
- int y;
- int priorty;
- int width;
-}
-point;
-
-point
-point_init(int x, int y, int width)
-{
- return (point) { x, y, 0, width };
-}
-
-int
-point_cmp_priority(const point* a, const point* b)
-{
- return c_default_cmp(&a->priorty, &b->priorty);
-}
-
-int
-point_equal(const point* a, const point* b)
-{
- return a->x == b->x && a->y == b->y;
-}
-
-point
-point_from(const cstr* maze, const char* c, int width)
-{
- int index = cstr_find(*maze, c);
- return point_init(index % width, index / width, width);
-}
-
-int
-point_index(const point* p)
-{
- return p->x + p->width * p->y;
-}
-
-int
-point_key_cmp(const point* a, const point* b)
-{
- int i = point_index(a);
- int j = point_index(b);
- return (i == j) ? 0 : (i < j) ? -1 : 1;
-}
-
-#define i_val point
-#define i_cmp point_cmp_priority
-#include <stc/cpque.h>
-
-#define i_val point
-#define i_opt c_no_cmp
-#include <stc/cdeq.h>
-
-#define i_key point
-#define i_val int
-#define i_cmp point_key_cmp
-#define i_tag pcost
-#include <stc/csmap.h>
-
-#define i_key point
-#define i_val point
-#define i_cmp point_key_cmp
-#define i_tag pstep
-#include <stc/csmap.h>
-
-cdeq_point
-astar(cstr* maze, int width)
-{
- cdeq_point path = cdeq_point_init();
-
- c_auto (cpque_point, front)
- c_auto (csmap_pstep, from)
- c_auto (csmap_pcost, costs)
- {
- point start = point_from(maze, "@", width);
- point goal = point_from(maze, "!", width);
- csmap_pcost_insert(&costs, start, 0);
- cpque_point_push(&front, start);
- while (!cpque_point_empty(front))
- {
- point current = *cpque_point_top(&front);
- cpque_point_pop(&front);
- if (point_equal(¤t, &goal))
- break;
- point deltas[] = {
- { -1, +1, 0, width }, { 0, +1, 0, width }, { 1, +1, 0, width },
- { -1, 0, 0, width }, /* ~ ~ ~ ~ ~ ~ ~ */ { 1, 0, 0, width },
- { -1, -1, 0, width }, { 0, -1, 0, width }, { 1, -1, 0, width },
- };
- for (size_t i = 0; i < c_arraylen(deltas); i++)
- {
- point delta = deltas[i];
- point next = point_init(current.x + delta.x, current.y + delta.y, width);
- int new_cost = *csmap_pcost_at(&costs, current);
- if (cstr_str(maze)[point_index(&next)] != '#')
- {
- const csmap_pcost_value *cost = csmap_pcost_get(&costs, next);
- if (cost == NULL || new_cost < cost->second)
- {
- csmap_pcost_insert(&costs, next, new_cost);
- next.priorty = new_cost + abs(goal.x - next.x) + abs(goal.y - next.y);
- cpque_point_push(&front, next);
- csmap_pstep_insert(&from, next, current);
- }
- }
- }
- }
- point current = goal;
- while (!point_equal(¤t, &start))
- {
- cdeq_point_push_front(&path, current);
- current = *csmap_pstep_at(&from, current);
- }
- cdeq_point_push_front(&path, start);
- }
- return path;
-}
-
-int
-main(void)
-{
- c_autovar (cstr maze = cstr_new(
- "#########################################################################\n"
- "# # # # # # #\n"
- "# # ######### # ##### ######### ##### ##### ##### # ! #\n"
- "# # # # # # # # # #\n"
- "######### # ######### ######### ##### # # # ######### #\n"
- "# # # # # # # # # # #\n"
- "# # ############# # # ######### ##### # ######### # #\n"
- "# # # # # # # # # #\n"
- "# ############# ##### ##### # ##### ######### # ##### #\n"
- "# # # # # # # # # #\n"
- "# ##### ##### # ##### # ######### # # # #############\n"
- "# # # # # # # # # # # #\n"
- "############# # # # ######### # ##### # ##### ##### #\n"
- "# # # # # # # # # #\n"
- "# ##### # ######### ##### # ##### ##### ############# #\n"
- "# # # # # # # # # #\n"
- "# # ######### # ##### ######### # # ############# # #\n"
- "# # # # # # # # # # #\n"
- "# ######### # # # ##### ######### ######### # #########\n"
- "# # # # # # # # # #\n"
- "# @ # ##### ##### ##### ######### ##### # ######### # #\n"
- "# # # # # # #\n"
- "#########################################################################\n"), cstr_drop(&maze))
- {
- int width = cstr_find(maze, "\n") + 1;
- c_autovar (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));
- }
- }
-}
+// +// -- An A* pathfinder inspired by the excellent tutorial at Red Blob Games -- +// +// This is a reimplementation of the CTL example to STC: +// https://github.com/glouw/ctl/blob/master/examples/astar.c +// https://www.redblobgames.com/pathfinding/a-star/introduction.html +#define i_implement +#include <stc/cstr.h> +#include <stdio.h> + +typedef struct +{ + int x; + int y; + int priorty; + int width; +} +point; + +point +point_init(int x, int y, int width) +{ + return (point) { x, y, 0, width }; +} + +int +point_cmp_priority(const point* a, const point* b) +{ + return c_default_cmp(&a->priorty, &b->priorty); +} + +int +point_equal(const point* a, const point* b) +{ + return a->x == b->x && a->y == b->y; +} + +point +point_from(const cstr* maze, const char* c, int width) +{ + int index = cstr_find(*maze, c); + return point_init(index % width, index / width, width); +} + +int +point_index(const point* p) +{ + return p->x + p->width * p->y; +} + +int +point_key_cmp(const point* a, const point* b) +{ + int i = point_index(a); + int j = point_index(b); + return (i == j) ? 0 : (i < j) ? -1 : 1; +} + +#define i_val point +#define i_cmp point_cmp_priority +#include <stc/cpque.h> + +#define i_val point +#define i_opt c_no_cmp +#include <stc/cdeq.h> + +#define i_key point +#define i_val int +#define i_cmp point_key_cmp +#define i_tag pcost +#include <stc/csmap.h> + +#define i_key point +#define i_val point +#define i_cmp point_key_cmp +#define i_tag pstep +#include <stc/csmap.h> + +cdeq_point +astar(cstr* maze, int width) +{ + cdeq_point path = cdeq_point_init(); + + c_auto (cpque_point, front) + c_auto (csmap_pstep, from) + c_auto (csmap_pcost, costs) + { + point start = point_from(maze, "@", width); + point goal = point_from(maze, "!", width); + csmap_pcost_insert(&costs, start, 0); + cpque_point_push(&front, start); + while (!cpque_point_empty(front)) + { + point current = *cpque_point_top(&front); + cpque_point_pop(&front); + if (point_equal(¤t, &goal)) + break; + point deltas[] = { + { -1, +1, 0, width }, { 0, +1, 0, width }, { 1, +1, 0, width }, + { -1, 0, 0, width }, /* ~ ~ ~ ~ ~ ~ ~ */ { 1, 0, 0, width }, + { -1, -1, 0, width }, { 0, -1, 0, width }, { 1, -1, 0, width }, + }; + for (size_t i = 0; i < c_arraylen(deltas); i++) + { + point delta = deltas[i]; + point next = point_init(current.x + delta.x, current.y + delta.y, width); + int new_cost = *csmap_pcost_at(&costs, current); + if (cstr_str(maze)[point_index(&next)] != '#') + { + const csmap_pcost_value *cost = csmap_pcost_get(&costs, next); + if (cost == NULL || new_cost < cost->second) + { + csmap_pcost_insert(&costs, next, new_cost); + next.priorty = new_cost + abs(goal.x - next.x) + abs(goal.y - next.y); + cpque_point_push(&front, next); + csmap_pstep_insert(&from, next, current); + } + } + } + } + point current = goal; + while (!point_equal(¤t, &start)) + { + cdeq_point_push_front(&path, current); + current = *csmap_pstep_at(&from, current); + } + cdeq_point_push_front(&path, start); + } + return path; +} + +int +main(void) +{ + c_autovar (cstr maze = cstr_new( + "#########################################################################\n" + "# # # # # # #\n" + "# # ######### # ##### ######### ##### ##### ##### # ! #\n" + "# # # # # # # # # #\n" + "######### # ######### ######### ##### # # # ######### #\n" + "# # # # # # # # # # #\n" + "# # ############# # # ######### ##### # ######### # #\n" + "# # # # # # # # # #\n" + "# ############# ##### ##### # ##### ######### # ##### #\n" + "# # # # # # # # # #\n" + "# ##### ##### # ##### # ######### # # # #############\n" + "# # # # # # # # # # # #\n" + "############# # # # ######### # ##### # ##### ##### #\n" + "# # # # # # # # # #\n" + "# ##### # ######### ##### # ##### ##### ############# #\n" + "# # # # # # # # # #\n" + "# # ######### # ##### ######### # # ############# # #\n" + "# # # # # # # # # # #\n" + "# ######### # # # ##### ######### ######### # #########\n" + "# # # # # # # # # #\n" + "# @ # ##### ##### ##### ######### ##### # ######### # #\n" + "# # # # # # #\n" + "#########################################################################\n"), cstr_drop(&maze)) + { + int width = cstr_find(maze, "\n") + 1; + c_autovar (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)); + } + } +} diff --git a/examples/birthday.c b/examples/birthday.c index 15d85e0c..50cd60dc 100644 --- a/examples/birthday.c +++ b/examples/birthday.c @@ -1,66 +1,66 @@ -#include <math.h>
-#include <stdio.h>
-#include <time.h>
-#define i_implement
-#include <stc/crandom.h>
-
-#define i_tag ic
-#define i_key uint64_t
-#define i_val uint8_t
-#include <stc/cmap.h>
-
-static uint64_t seed = 12345;
-
-static void test_repeats(void)
-{
- enum {BITS = 46, BITS_TEST = BITS/2 + 2};
- const static uint64_t N = 1ull << BITS_TEST;
- const static uint64_t mask = (1ull << BITS) - 1;
-
- 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 %" PRIuMAX " (%d) at 2^%d\n", k, v, (int) log2((double) i));
- }
- }
-}
-
-#define i_key uint32_t
-#define i_val uint64_t
-#define i_tag x
-#include <stc/cmap.h>
-
-void test_distribution(void)
-{
- enum {BITS = 26};
- printf("distribution test: 2^%d values\n", BITS);
- 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;
- }
-
- uint64_t sum = 0;
- c_foreach (i, cmap_x, map) sum += i.ref->second;
- sum /= map.size;
-
- c_foreach (i, cmap_x, map) {
- printf("%4u: %" PRIuMAX " - %" PRIuMAX ": %11.8f\n", i.ref->first, i.ref->second, sum, (1 - (double) i.ref->second / sum));
- }
- }
-}
-
-int main()
-{
- seed = time(NULL);
- test_distribution();
- test_repeats();
-}
+#include <math.h> +#include <stdio.h> +#include <time.h> +#define i_implement +#include <stc/crandom.h> + +#define i_tag ic +#define i_key uint64_t +#define i_val uint8_t +#include <stc/cmap.h> + +static uint64_t seed = 12345; + +static void test_repeats(void) +{ + enum {BITS = 46, BITS_TEST = BITS/2 + 2}; + const static uint64_t N = 1ull << BITS_TEST; + const static uint64_t mask = (1ull << BITS) - 1; + + 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 %" PRIuMAX " (%d) at 2^%d\n", k, v, (int) log2((double) i)); + } + } +} + +#define i_key uint32_t +#define i_val uint64_t +#define i_tag x +#include <stc/cmap.h> + +void test_distribution(void) +{ + enum {BITS = 26}; + printf("distribution test: 2^%d values\n", BITS); + 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; + } + + uint64_t sum = 0; + c_foreach (i, cmap_x, map) sum += i.ref->second; + sum /= map.size; + + c_foreach (i, cmap_x, map) { + printf("%4u: %" PRIuMAX " - %" PRIuMAX ": %11.8f\n", i.ref->first, i.ref->second, sum, (1 - (double) i.ref->second / sum)); + } + } +} + +int main() +{ + seed = time(NULL); + test_distribution(); + test_repeats(); +} diff --git a/examples/bits.c b/examples/bits.c index 051beb02..71fe1ee0 100644 --- a/examples/bits.c +++ b/examples/bits.c @@ -1,63 +1,63 @@ -#include <stdio.h>
-#define i_implement
-#include <stc/cbits.h>
-
-int main()
-{
- c_autovar (cbits set = cbits_with_size(23, true), cbits_drop(&set)) {
- printf("count %" PRIuMAX ", %" PRIuMAX "\n", cbits_count(&set), cbits_size(&set));
- cbits s1 = cbits_from("1110100110111");
- char buf[256];
- cbits_to_str(&s1, buf, 0, -1);
- printf("buf: %s: %" PRIuMAX "\n", buf, cbits_count(&s1));
- cbits_drop(&s1);
-
- cbits_reset(&set, 9);
- cbits_resize(&set, 43, false);
- c_autobuf (str, char, cbits_size(&set) + 1)
- printf(" str: %s\n", cbits_to_str(&set, str, 0, -1));
-
- printf("%4" PRIuMAX ": ", cbits_size(&set));
- c_forrange (i, cbits_size(&set))
- printf("%d", cbits_test(&set, i));
- puts("");
-
- cbits_set(&set, 28);
- cbits_resize(&set, 77, true);
- cbits_resize(&set, 93, false);
- cbits_resize(&set, 102, true);
- cbits_set_value(&set, 99, false);
- printf("%4" PRIuMAX ": ", cbits_size(&set));
- c_forrange (i, cbits_size(&set))
- printf("%d", cbits_test(&set, i));
-
- puts("\nIterate:");
- printf("%4" PRIuMAX ": ", cbits_size(&set));
- c_forrange (i, cbits_size(&set))
- printf("%d", cbits_test(&set, i));
- puts("");
-
- c_autovar (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" PRIuMAX ": ", cbits_size(&set));
- c_forrange (i, cbits_size(&set))
- printf("%d", cbits_test(&set, i));
- puts("");
- }
- }
-}
+#include <stdio.h> +#define i_implement +#include <stc/cbits.h> + +int main() +{ + c_autovar (cbits set = cbits_with_size(23, true), cbits_drop(&set)) { + printf("count %" PRIuMAX ", %" PRIuMAX "\n", cbits_count(&set), cbits_size(&set)); + cbits s1 = cbits_from("1110100110111"); + char buf[256]; + cbits_to_str(&s1, buf, 0, -1); + printf("buf: %s: %" PRIuMAX "\n", buf, cbits_count(&s1)); + cbits_drop(&s1); + + cbits_reset(&set, 9); + cbits_resize(&set, 43, false); + c_autobuf (str, char, cbits_size(&set) + 1) + printf(" str: %s\n", cbits_to_str(&set, str, 0, -1)); + + printf("%4" PRIuMAX ": ", cbits_size(&set)); + c_forrange (i, cbits_size(&set)) + printf("%d", cbits_test(&set, i)); + puts(""); + + cbits_set(&set, 28); + cbits_resize(&set, 77, true); + cbits_resize(&set, 93, false); + cbits_resize(&set, 102, true); + cbits_set_value(&set, 99, false); + printf("%4" PRIuMAX ": ", cbits_size(&set)); + c_forrange (i, cbits_size(&set)) + printf("%d", cbits_test(&set, i)); + + puts("\nIterate:"); + printf("%4" PRIuMAX ": ", cbits_size(&set)); + c_forrange (i, cbits_size(&set)) + printf("%d", cbits_test(&set, i)); + puts(""); + + c_autovar (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" PRIuMAX ": ", cbits_size(&set)); + c_forrange (i, cbits_size(&set)) + printf("%d", cbits_test(&set, i)); + puts(""); + } + } +} diff --git a/examples/bits2.c b/examples/bits2.c index af87df42..4b16ad76 100644 --- a/examples/bits2.c +++ b/examples/bits2.c @@ -1,43 +1,43 @@ -#include <stdio.h>
-// Example of static sized (stack allocated) bitsets
-
-#define i_type Bits
-#define i_len 80 // enable fixed bitset on the stack
-#define i_implement
-#include <stc/cbits.h>
-
-int main()
-{
- Bits s1 = Bits_from("1110100110111");
-
- printf("size %" PRIuMAX "\n", Bits_size(&s1));
- char buf[256];
- Bits_to_str(&s1, buf, 0, -1);
- printf("buf: %s: count=%" PRIuMAX "\n", buf, Bits_count(&s1));
-
- Bits_reset(&s1, 8);
- c_autobuf (str, char, Bits_size(&s1) + 1)
- printf(" s1: %s\n", Bits_to_str(&s1, str, 0, -1));
-
- Bits s2 = Bits_clone(s1);
-
- Bits_flip_all(&s2);
- Bits_reset(&s2, 66);
- Bits_reset(&s2, 67);
- printf(" s2: ");
- c_forrange (i, Bits_size(&s2))
- printf("%d", Bits_test(&s2, i));
- puts("");
-
- printf("xor: ");
- Bits_xor(&s1, &s2);
- c_forrange (i, Bits_size(&s1))
- printf("%d", Bits_test(&s1, i));
- puts("");
-
- printf("all: ");
- Bits_set_pattern(&s1, 0x3333333333333333);
- c_forrange (i, Bits_size(&s1))
- printf("%d", Bits_test(&s1, i));
- puts("");
-}
+#include <stdio.h> +// Example of static sized (stack allocated) bitsets + +#define i_type Bits +#define i_len 80 // enable fixed bitset on the stack +#define i_implement +#include <stc/cbits.h> + +int main() +{ + Bits s1 = Bits_from("1110100110111"); + + printf("size %" PRIuMAX "\n", Bits_size(&s1)); + char buf[256]; + Bits_to_str(&s1, buf, 0, -1); + printf("buf: %s: count=%" PRIuMAX "\n", buf, Bits_count(&s1)); + + Bits_reset(&s1, 8); + c_autobuf (str, char, Bits_size(&s1) + 1) + printf(" s1: %s\n", Bits_to_str(&s1, str, 0, -1)); + + Bits s2 = Bits_clone(s1); + + Bits_flip_all(&s2); + Bits_reset(&s2, 66); + Bits_reset(&s2, 67); + printf(" s2: "); + c_forrange (i, Bits_size(&s2)) + printf("%d", Bits_test(&s2, i)); + puts(""); + + printf("xor: "); + Bits_xor(&s1, &s2); + c_forrange (i, Bits_size(&s1)) + printf("%d", Bits_test(&s1, i)); + puts(""); + + printf("all: "); + Bits_set_pattern(&s1, 0x3333333333333333); + c_forrange (i, Bits_size(&s1)) + printf("%d", Bits_test(&s1, i)); + puts(""); +} diff --git a/examples/books.c b/examples/books.c index de724a19..5677ff3a 100644 --- a/examples/books.c +++ b/examples/books.c @@ -1,61 +1,61 @@ -// https://doc.rust-lang.org/std/collections/struct.HashMap.html
-#define i_implement
-#include <stc/cstr.h>
-#define i_key_str
-#define i_val_str
-#include <stc/cmap.h>
-
-// Type inference lets us omit an explicit type signature (which
-// would be `HashMap<String, String>` in this example).
-int main()
-{
- c_auto (cmap_str, book_reviews)
- {
- // Review some books.
- cmap_str_emplace(&book_reviews,
- "Adventures of Huckleberry Finn",
- "My favorite book."
- );
- cmap_str_emplace(&book_reviews,
- "Grimms' Fairy Tales",
- "Masterpiece."
- );
- cmap_str_emplace(&book_reviews,
- "Pride and Prejudice",
- "Very enjoyable"
- );
- cmap_str_insert(&book_reviews,
- cstr_new("The Adventures of Sherlock Holmes"),
- cstr_new("Eye lyked it alot.")
- );
-
- // Check for a specific one.
- // When collections store owned values (String), they can still be
- // queried using references (&str).
- if (cmap_str_contains(&book_reviews, "Les Misérables")) {
- printf("We've got %" PRIuMAX " reviews, but Les Misérables ain't one.",
- cmap_str_size(book_reviews));
- }
-
- // oops, this review has a lot of spelling mistakes, let's delete it.
- cmap_str_erase(&book_reviews, "The Adventures of Sherlock Holmes");
-
- // Look up the values associated with some keys.
- const char* to_find[] = {"Pride and Prejudice", "Alice's Adventure in Wonderland"};
- c_forrange (i, c_arraylen(to_find)) {
- const cmap_str_value* b;
- if ((b = cmap_str_get(&book_reviews, to_find[i])))
- printf("%s: %s\n", cstr_str(&b->first), cstr_str(&b->second));
- else
- printf("%s is unreviewed.\n", to_find[i]);
- }
-
- // Look up the value for a key (will panic if the key is not found).
- printf("Review for Jane: %s\n", cstr_str(cmap_str_at(&book_reviews, "Pride and Prejudice")));
-
- // Iterate over everything.
- c_forpair (book, review, cmap_str, book_reviews) {
- printf("%s: \"%s\"\n", cstr_str(_.book), cstr_str(_.review));
- }
- }
-}
+// https://doc.rust-lang.org/std/collections/struct.HashMap.html +#define i_implement +#include <stc/cstr.h> +#define i_key_str +#define i_val_str +#include <stc/cmap.h> + +// Type inference lets us omit an explicit type signature (which +// would be `HashMap<String, String>` in this example). +int main() +{ + c_auto (cmap_str, book_reviews) + { + // Review some books. + cmap_str_emplace(&book_reviews, + "Adventures of Huckleberry Finn", + "My favorite book." + ); + cmap_str_emplace(&book_reviews, + "Grimms' Fairy Tales", + "Masterpiece." + ); + cmap_str_emplace(&book_reviews, + "Pride and Prejudice", + "Very enjoyable" + ); + cmap_str_insert(&book_reviews, + cstr_new("The Adventures of Sherlock Holmes"), + cstr_new("Eye lyked it alot.") + ); + + // Check for a specific one. + // When collections store owned values (String), they can still be + // queried using references (&str). + if (cmap_str_contains(&book_reviews, "Les Misérables")) { + printf("We've got %" PRIuMAX " reviews, but Les Misérables ain't one.", + cmap_str_size(book_reviews)); + } + + // oops, this review has a lot of spelling mistakes, let's delete it. + cmap_str_erase(&book_reviews, "The Adventures of Sherlock Holmes"); + + // Look up the values associated with some keys. + const char* to_find[] = {"Pride and Prejudice", "Alice's Adventure in Wonderland"}; + c_forrange (i, c_arraylen(to_find)) { + const cmap_str_value* b; + if ((b = cmap_str_get(&book_reviews, to_find[i]))) + printf("%s: %s\n", cstr_str(&b->first), cstr_str(&b->second)); + else + printf("%s is unreviewed.\n", to_find[i]); + } + + // Look up the value for a key (will panic if the key is not found). + printf("Review for Jane: %s\n", cstr_str(cmap_str_at(&book_reviews, "Pride and Prejudice"))); + + // Iterate over everything. + c_forpair (book, review, cmap_str, book_reviews) { + printf("%s: \"%s\"\n", cstr_str(_.book), cstr_str(_.review)); + } + } +} diff --git a/examples/box.c b/examples/box.c index 4502f479..7a984a21 100644 --- a/examples/box.c +++ b/examples/box.c @@ -1,75 +1,75 @@ -/* cbox: heap allocated boxed type */
-#define i_implement
-#include <stc/cstr.h>
-
-typedef struct { cstr name, last; } Person;
-
-Person Person_new(const char* name, const char* last) {
- return (Person){.name = cstr_from(name), .last = cstr_from(last)};
-}
-
-uint64_t Person_hash(const Person* a) {
- return cstr_hash(&a->name) ^ cstr_hash(&a->last);
-}
-
-int Person_cmp(const Person* a, const Person* b) {
- int c = cstr_cmp(&a->name, &b->name);
- return c ? c : cstr_cmp(&a->last, &b->last);
-}
-
-Person Person_clone(Person p) {
- p.name = cstr_clone(p.name);
- p.last = cstr_clone(p.last);
- return p;
-}
-
-void Person_drop(Person* p) {
- printf("drop: %s %s\n", cstr_str(&p->name), cstr_str(&p->last));
- c_drop(cstr, &p->name, &p->last);
-}
-
-#define i_type PBox
-#define i_val_bind Person // binds Person_cmp, ...
-#include <stc/cbox.h>
-
-#define i_type Persons
-#define i_val_arcbox PBox // informs that PBox is a smart pointer.
-#include <stc/cvec.h>
-
-int main()
-{
- c_auto (Persons, vec)
- c_auto (PBox, p, q)
- {
- p = PBox_make(Person_new("Laura", "Palmer"));
-
- q = PBox_clone(p);
- cstr_assign(&q.get->name, "Leland");
-
- printf("orig: %s %s\n", cstr_str(&p.get->name), cstr_str(&p.get->last));
- printf("copy: %s %s\n", cstr_str(&q.get->name), cstr_str(&q.get->last));
-
- Persons_push_back(&vec, PBox_make(Person_new("Dale", "Cooper")));
- Persons_push_back(&vec, PBox_make(Person_new("Audrey", "Home")));
-
- // NB! Clone p and q to the vector using emplace_back()
- c_apply(v, Persons_push_back(&vec, PBox_clone(*v)), PBox, {p, q});
-
- c_foreach (i, Persons, vec)
- printf("%s %s\n", cstr_str(&i.ref->get->name), cstr_str(&i.ref->get->last));
- puts("");
-
- // Look-up Audrey! Use a (fake) temporary PBox for lookup.
- c_autovar (Person a = Person_new("Audrey", "Home"), Person_drop(&a)) {
- const PBox *v = Persons_get(&vec, a);
- if (v) printf("found: %s %s\n", cstr_str(&v->get->name), cstr_str(&v->get->last));
- }
- puts("");
-
- // Alternative to use cbox (when not placed in container).
- Person *she = c_new(Person, Person_new("Shelly", "Johnson"));
- printf("%s %s\n", cstr_str(&she->name), cstr_str(&she->last));
- c_delete(Person, she); // drop and free
- puts("");
- }
-}
+/* cbox: heap allocated boxed type */ +#define i_implement +#include <stc/cstr.h> + +typedef struct { cstr name, last; } Person; + +Person Person_new(const char* name, const char* last) { + return (Person){.name = cstr_from(name), .last = cstr_from(last)}; +} + +uint64_t Person_hash(const Person* a) { + return cstr_hash(&a->name) ^ cstr_hash(&a->last); +} + +int Person_cmp(const Person* a, const Person* b) { + int c = cstr_cmp(&a->name, &b->name); + return c ? c : cstr_cmp(&a->last, &b->last); +} + +Person Person_clone(Person p) { + p.name = cstr_clone(p.name); + p.last = cstr_clone(p.last); + return p; +} + +void Person_drop(Person* p) { + printf("drop: %s %s\n", cstr_str(&p->name), cstr_str(&p->last)); + c_drop(cstr, &p->name, &p->last); +} + +#define i_type PBox +#define i_val_bind Person // binds Person_cmp, ... +#include <stc/cbox.h> + +#define i_type Persons +#define i_val_arcbox PBox // informs that PBox is a smart pointer. +#include <stc/cvec.h> + +int main() +{ + c_auto (Persons, vec) + c_auto (PBox, p, q) + { + p = PBox_make(Person_new("Laura", "Palmer")); + + q = PBox_clone(p); + cstr_assign(&q.get->name, "Leland"); + + printf("orig: %s %s\n", cstr_str(&p.get->name), cstr_str(&p.get->last)); + printf("copy: %s %s\n", cstr_str(&q.get->name), cstr_str(&q.get->last)); + + Persons_push_back(&vec, PBox_make(Person_new("Dale", "Cooper"))); + Persons_push_back(&vec, PBox_make(Person_new("Audrey", "Home"))); + + // NB! Clone p and q to the vector using emplace_back() + c_apply(v, Persons_push_back(&vec, PBox_clone(*v)), PBox, {p, q}); + + c_foreach (i, Persons, vec) + printf("%s %s\n", cstr_str(&i.ref->get->name), cstr_str(&i.ref->get->last)); + puts(""); + + // Look-up Audrey! Use a (fake) temporary PBox for lookup. + c_autovar (Person a = Person_new("Audrey", "Home"), Person_drop(&a)) { + const PBox *v = Persons_get(&vec, a); + if (v) printf("found: %s %s\n", cstr_str(&v->get->name), cstr_str(&v->get->last)); + } + puts(""); + + // Alternative to use cbox (when not placed in container). + Person *she = c_new(Person, Person_new("Shelly", "Johnson")); + printf("%s %s\n", cstr_str(&she->name), cstr_str(&she->last)); + c_delete(Person, she); // drop and free + puts(""); + } +} diff --git a/examples/box2.c b/examples/box2.c index 2d1b82fc..c44802d3 100644 --- a/examples/box2.c +++ b/examples/box2.c @@ -1,88 +1,88 @@ -// https://doc.rust-lang.org/rust-by-example/std/box.html
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <stc/ccommon.h>
-
-struct {
- double x;
- double y;
-} typedef Point;
-
-// A Rectangle can be specified by where its top left and bottom right
-// corners are in space
-struct {
- Point top_left;
- Point bottom_right;
-} typedef Rectangle;
-
-#define i_val Point
-#define i_opt c_no_cmp
-#include <stc/cbox.h> // cbox_Point
-
-#define i_val Rectangle
-#define i_opt c_no_cmp
-#include <stc/cbox.h> // cbox_Rectangle
-
-// Box in box:
-#define i_val_arcbox cbox_Point // NB: use i_val_arcbox when value is a cbox or carc!
- // it will auto-set i_valdrop, i_valfrom, i_cmp for you.
-#define i_opt c_no_cmp
-#define i_tag BoxPoint
-#include <stc/cbox.h> // cbox_BoxPoint
-
-Point origin(void) {
- return (Point){ .x=0.0, .y=0.0 };
-}
-
-cbox_Point boxed_origin(void) {
- // Allocate this point on the heap, and return a pointer to it
- return cbox_Point_make((Point){ .x=0.0, .y=0.0 });
-}
-
-
-int main(void) {
- // (all the type annotations are superfluous)
- // Stack allocated variables
- Point point = origin();
- Rectangle rectangle = (Rectangle){
- .top_left = origin(),
- .bottom_right = (Point){ .x=3.0, .y=-4.0 }
- };
-
- // Heap allocated rectangle
- c_auto (cbox_Rectangle, boxed_rectangle)
- c_auto (cbox_Point, boxed_point)
- c_auto (cbox_BoxPoint, box_in_a_box)
- {
- boxed_rectangle = cbox_Rectangle_make((Rectangle){
- .top_left = origin(),
- .bottom_right = (Point){ .x=3.0, .y=-4.0 }
- });
-
- // The output of functions can be boxed
- boxed_point = cbox_Point_make(origin());
-
- // Double indirection
- box_in_a_box = cbox_BoxPoint_make(boxed_origin());
-
- printf("Point occupies %" PRIuMAX " bytes on the stack\n",
- sizeof(point));
- printf("Rectangle occupies %" PRIuMAX " bytes on the stack\n",
- sizeof(rectangle));
-
- // box size == pointer size
- printf("Boxed point occupies %" PRIuMAX " bytes on the stack\n",
- sizeof(boxed_point));
- printf("Boxed rectangle occupies %" PRIuMAX " bytes on the stack\n",
- sizeof(boxed_rectangle));
- printf("Boxed box occupies %" PRIuMAX " bytes on the stack\n",
- sizeof(box_in_a_box));
-
- // Copy the data contained in `boxed_point` into `unboxed_point`
- Point unboxed_point = *boxed_point.get;
- printf("Unboxed point occupies %" PRIuMAX " bytes on the stack\n",
- sizeof(unboxed_point));
- }
-}
+// https://doc.rust-lang.org/rust-by-example/std/box.html + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <stc/ccommon.h> + +struct { + double x; + double y; +} typedef Point; + +// A Rectangle can be specified by where its top left and bottom right +// corners are in space +struct { + Point top_left; + Point bottom_right; +} typedef Rectangle; + +#define i_val Point +#define i_opt c_no_cmp +#include <stc/cbox.h> // cbox_Point + +#define i_val Rectangle +#define i_opt c_no_cmp +#include <stc/cbox.h> // cbox_Rectangle + +// Box in box: +#define i_val_arcbox cbox_Point // NB: use i_val_arcbox when value is a cbox or carc! + // it will auto-set i_valdrop, i_valfrom, i_cmp for you. +#define i_opt c_no_cmp +#define i_tag BoxPoint +#include <stc/cbox.h> // cbox_BoxPoint + +Point origin(void) { + return (Point){ .x=0.0, .y=0.0 }; +} + +cbox_Point boxed_origin(void) { + // Allocate this point on the heap, and return a pointer to it + return cbox_Point_make((Point){ .x=0.0, .y=0.0 }); +} + + +int main(void) { + // (all the type annotations are superfluous) + // Stack allocated variables + Point point = origin(); + Rectangle rectangle = (Rectangle){ + .top_left = origin(), + .bottom_right = (Point){ .x=3.0, .y=-4.0 } + }; + + // Heap allocated rectangle + c_auto (cbox_Rectangle, boxed_rectangle) + c_auto (cbox_Point, boxed_point) + c_auto (cbox_BoxPoint, box_in_a_box) + { + boxed_rectangle = cbox_Rectangle_make((Rectangle){ + .top_left = origin(), + .bottom_right = (Point){ .x=3.0, .y=-4.0 } + }); + + // The output of functions can be boxed + boxed_point = cbox_Point_make(origin()); + + // Double indirection + box_in_a_box = cbox_BoxPoint_make(boxed_origin()); + + printf("Point occupies %" PRIuMAX " bytes on the stack\n", + sizeof(point)); + printf("Rectangle occupies %" PRIuMAX " bytes on the stack\n", + sizeof(rectangle)); + + // box size == pointer size + printf("Boxed point occupies %" PRIuMAX " bytes on the stack\n", + sizeof(boxed_point)); + printf("Boxed rectangle occupies %" PRIuMAX " bytes on the stack\n", + sizeof(boxed_rectangle)); + printf("Boxed box occupies %" PRIuMAX " bytes on the stack\n", + sizeof(box_in_a_box)); + + // Copy the data contained in `boxed_point` into `unboxed_point` + Point unboxed_point = *boxed_point.get; + printf("Unboxed point occupies %" PRIuMAX " bytes on the stack\n", + sizeof(unboxed_point)); + } +} diff --git a/examples/city.c b/examples/city.c index 8ee1576f..c359ebdf 100644 --- a/examples/city.c +++ b/examples/city.c @@ -1,83 +1,83 @@ -#define i_implement
-#include <stc/cstr.h>
-
-typedef struct {
- cstr name;
- cstr country;
- float lat, lon;
- int population;
-} City;
-
-static inline 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);
-}
-
-static inline uint64_t City_hash(const City* a) {
- printf("hash %s\n", cstr_str(&a->name));
- return cstr_hash(&a->name) ^ cstr_hash(&a->country);
-}
-
-static inline City City_clone(City c) {
- printf("clone %s\n", cstr_str(&c.name));
- c.name = cstr_clone(c.name);
- c.country = cstr_clone(c.country);
- return c;
-}
-
-static inline void City_drop(City* c) {
- printf("drop %s\n", cstr_str(&c->name));
- c_drop(cstr, &c->name, &c->country);
-}
-
-
-#define i_type CityArc
-#define i_key_bind City
-#include <stc/cbox.h>
-//#include <stc/carc.h> // try instead of cbox.h
-
-#define i_type Cities
-#define i_key_arcbox CityArc
-#include <stc/cvec.h>
-
-#define i_type CityMap
-#define i_key int
-#define i_val_arcbox CityArc
-#include <stc/csmap.h>
-
-
-int main(void)
-{
- c_auto (Cities, cities, copy)
- c_auto (CityMap, map)
- {
- struct City_s { const char *name, *country; float lat, lon; int pop; };
-
- c_apply(c, Cities_push(&cities, CityArc_make((City){cstr_from(c->name), cstr_from(c->country),
- c->lat, c->lon, c->pop})), struct City_s, {
- {"New York", "US", 4.3, 23.2, 9000000},
- {"Paris", "France", 4.3, 23.2, 9000000},
- {"Berlin", "Germany", 4.3, 23.2, 9000000},
- {"London", "UK", 4.3, 23.2, 9000000},
- });
-
- copy = Cities_clone(cities); // share each element!
-
- 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:%s, %d, 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("id:%d, city:%s, %d, use:%ld\n", *_.id, cstr_str(&_.city->get->name),
- _.city->get->population, CityArc_use_count(*_.city));
- puts("");
- }
-}
+#define i_implement +#include <stc/cstr.h> + +typedef struct { + cstr name; + cstr country; + float lat, lon; + int population; +} City; + +static inline 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); +} + +static inline uint64_t City_hash(const City* a) { + printf("hash %s\n", cstr_str(&a->name)); + return cstr_hash(&a->name) ^ cstr_hash(&a->country); +} + +static inline City City_clone(City c) { + printf("clone %s\n", cstr_str(&c.name)); + c.name = cstr_clone(c.name); + c.country = cstr_clone(c.country); + return c; +} + +static inline void City_drop(City* c) { + printf("drop %s\n", cstr_str(&c->name)); + c_drop(cstr, &c->name, &c->country); +} + + +#define i_type CityArc +#define i_key_bind City +#include <stc/cbox.h> +//#include <stc/carc.h> // try instead of cbox.h + +#define i_type Cities +#define i_key_arcbox CityArc +#include <stc/cvec.h> + +#define i_type CityMap +#define i_key int +#define i_val_arcbox CityArc +#include <stc/csmap.h> + + +int main(void) +{ + c_auto (Cities, cities, copy) + c_auto (CityMap, map) + { + struct City_s { const char *name, *country; float lat, lon; int pop; }; + + c_apply(c, Cities_push(&cities, CityArc_make((City){cstr_from(c->name), cstr_from(c->country), + c->lat, c->lon, c->pop})), struct City_s, { + {"New York", "US", 4.3, 23.2, 9000000}, + {"Paris", "France", 4.3, 23.2, 9000000}, + {"Berlin", "Germany", 4.3, 23.2, 9000000}, + {"London", "UK", 4.3, 23.2, 9000000}, + }); + + copy = Cities_clone(cities); // share each element! + + 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:%s, %d, 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("id:%d, city:%s, %d, use:%ld\n", *_.id, cstr_str(&_.city->get->name), + _.city->get->population, CityArc_use_count(*_.city)); + puts(""); + } +} diff --git a/examples/complex.c b/examples/complex.c index c5ac9882..8db85bbd 100644 --- a/examples/complex.c +++ b/examples/complex.c @@ -1,63 +1,63 @@ -#define i_implement
-#include <stc/cstr.h>
-
-void check_drop(float* v) {printf("destroy %g\n", *v);}
-
-#define i_type FloatStack
-#define i_val float
-#define i_valdrop check_drop
-#define i_valclone(x) x // required to allow cloning when i_valdrop is defined
- // (not for carc as it does not use i_valclone to clone).
-#include <stc/cstack.h>
-
-#define i_type StackList
-#define i_val_bind FloatStack
-#define i_opt c_no_cmp
-#include <stc/clist.h>
-
-#define i_type ListMap
-#define i_key int
-#define i_val_bind StackList
-#include <stc/cmap.h>
-
-#define i_type MapMap
-#define i_key_str
-#define i_val_bind ListMap
-#include <stc/cmap.h>
-
-// c++:
-// using FloatStack = std::stack<float>;
-// using map_lst = std::unordered_map<int, std::forward_list<array2f>>;
-// using map_map = std::unordered_map<std::string, map_lst>;
-
-int main() {
- int xdim = 4, ydim = 6;
- int x = 1, tableKey = 42;
- const char* strKey = "first";
-
- c_auto (MapMap, mmap)
- {
- FloatStack stack = FloatStack_with_capacity(xdim * ydim);
- memset(stack.data, 0, xdim*ydim*sizeof *stack.data);
- stack.size = stack.capacity;
-
- // Put in some data in stack array
- stack.data[x] = 3.1415927f;
- printf("stack size: %" PRIuMAX "\n", FloatStack_size(stack));
-
- StackList list = StackList_init();
- StackList_push_back(&list, stack);
-
- ListMap lmap = ListMap_init();
- ListMap_insert(&lmap, tableKey, list);
- MapMap_insert(&mmap, cstr_from(strKey), lmap);
-
- // Access the data entry
- const ListMap* lmap_p = MapMap_at(&mmap, strKey);
- const StackList* list_p = ListMap_at(lmap_p, tableKey);
- const FloatStack* stack_p = StackList_back(list_p);
- printf("value (%d) is: %f\n", x, *FloatStack_at(stack_p, x));
-
- stack.data[x] = 1.41421356f; // change the value in array
- }
-}
+#define i_implement +#include <stc/cstr.h> + +void check_drop(float* v) {printf("destroy %g\n", *v);} + +#define i_type FloatStack +#define i_val float +#define i_valdrop check_drop +#define i_valclone(x) x // required to allow cloning when i_valdrop is defined + // (not for carc as it does not use i_valclone to clone). +#include <stc/cstack.h> + +#define i_type StackList +#define i_val_bind FloatStack +#define i_opt c_no_cmp +#include <stc/clist.h> + +#define i_type ListMap +#define i_key int +#define i_val_bind StackList +#include <stc/cmap.h> + +#define i_type MapMap +#define i_key_str +#define i_val_bind ListMap +#include <stc/cmap.h> + +// c++: +// using FloatStack = std::stack<float>; +// using map_lst = std::unordered_map<int, std::forward_list<array2f>>; +// using map_map = std::unordered_map<std::string, map_lst>; + +int main() { + int xdim = 4, ydim = 6; + int x = 1, tableKey = 42; + const char* strKey = "first"; + + c_auto (MapMap, mmap) + { + FloatStack stack = FloatStack_with_capacity(xdim * ydim); + memset(stack.data, 0, xdim*ydim*sizeof *stack.data); + stack.size = stack.capacity; + + // Put in some data in stack array + stack.data[x] = 3.1415927f; + printf("stack size: %" PRIuMAX "\n", FloatStack_size(stack)); + + StackList list = StackList_init(); + StackList_push_back(&list, stack); + + ListMap lmap = ListMap_init(); + ListMap_insert(&lmap, tableKey, list); + MapMap_insert(&mmap, cstr_from(strKey), lmap); + + // Access the data entry + const ListMap* lmap_p = MapMap_at(&mmap, strKey); + const StackList* list_p = ListMap_at(lmap_p, tableKey); + const FloatStack* stack_p = StackList_back(list_p); + printf("value (%d) is: %f\n", x, *FloatStack_at(stack_p, x)); + + stack.data[x] = 1.41421356f; // change the value in array + } +} diff --git a/examples/csmap_insert.c b/examples/csmap_insert.c index 24f536e9..3d235877 100644 --- a/examples/csmap_insert.c +++ b/examples/csmap_insert.c @@ -1,112 +1,112 @@ -#define i_implement
-#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>
-
-#define i_key int
-#define i_val_str
-#define i_tag istr // Map of int => cstr
-#include <stc/csmap.h>
-
-#define i_val csmap_ii_raw
-#define i_opt c_no_cmp
-#define i_tag ii
-#include <stc/cvec.h>
-
-void print_ii(csmap_ii map) {
- c_foreach (e, csmap_ii, map)
- printf("(%d, %d) ", e.ref->first, e.ref->second);
- puts("");
-}
-
-void print_istr(csmap_istr map) {
- c_foreach (e, csmap_istr, map)
- printf("(%d, %s) ", e.ref->first, cstr_str(&e.ref->second));
- puts("");
-}
-
-int main()
-{
- // 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);
- 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_back(&v, (ipair){43, 294});
- cvec_ii_push_back(&v, (ipair){41, 262});
- cvec_ii_push_back(&v, (ipair){45, 330});
- cvec_ii_push_back(&v, (ipair){42, 277});
- cvec_ii_push_back(&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_new("blue")}, ip2 = {510, cstr_new("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
- c_apply(v, csmap_ii_insert(&m4, c_pair(v)), csmap_ii_raw, {
- { 4, 44 }, { 2, 22 }, { 3, 33 }, { 1, 11 }, { 5, 55 }
- });
- puts("After initializer_list insertion, m4 contains:");
- print_ii(m4);
- puts("");
- }
-}
+#define i_implement +#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> + +#define i_key int +#define i_val_str +#define i_tag istr // Map of int => cstr +#include <stc/csmap.h> + +#define i_val csmap_ii_raw +#define i_opt c_no_cmp +#define i_tag ii +#include <stc/cvec.h> + +void print_ii(csmap_ii map) { + c_foreach (e, csmap_ii, map) + printf("(%d, %d) ", e.ref->first, e.ref->second); + puts(""); +} + +void print_istr(csmap_istr map) { + c_foreach (e, csmap_istr, map) + printf("(%d, %s) ", e.ref->first, cstr_str(&e.ref->second)); + puts(""); +} + +int main() +{ + // 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); + 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_back(&v, (ipair){43, 294}); + cvec_ii_push_back(&v, (ipair){41, 262}); + cvec_ii_push_back(&v, (ipair){45, 330}); + cvec_ii_push_back(&v, (ipair){42, 277}); + cvec_ii_push_back(&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_new("blue")}, ip2 = {510, cstr_new("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 + c_apply(v, csmap_ii_insert(&m4, c_pair(v)), csmap_ii_raw, { + { 4, 44 }, { 2, 22 }, { 3, 33 }, { 1, 11 }, { 5, 55 } + }); + puts("After initializer_list insertion, m4 contains:"); + print_ii(m4); + puts(""); + } +} diff --git a/examples/csset_erase.c b/examples/csset_erase.c index 3cfaa7f1..7c8c1d97 100644 --- a/examples/csset_erase.c +++ b/examples/csset_erase.c @@ -1,42 +1,42 @@ -#include <stdio.h>
-
-#define i_key int
-#include <stc/csset.h>
-
-int main()
-{
- c_auto (csset_int, set)
- {
- c_apply(v, csset_int_insert(&set, *v),
- 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 != csset_int_end(&set).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("");
- }
-}
+#include <stdio.h> + +#define i_key int +#include <stc/csset.h> + +int main() +{ + c_auto (csset_int, set) + { + c_apply(v, csset_int_insert(&set, *v), + 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 != csset_int_end(&set).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(""); + } +} diff --git a/examples/cstr_match.c b/examples/cstr_match.c index a110e49a..69c12ef2 100644 --- a/examples/cstr_match.c +++ b/examples/cstr_match.c @@ -1,23 +1,23 @@ -#define i_implement
-#include <stc/cstr.h>
-#include <stc/csview.h>
-#include <stdio.h>
-
-int main()
-{
- c_autovar (cstr ss = cstr_new("The quick brown fox jumps over the lazy dog.JPG"), cstr_drop(&ss)) {
- size_t pos = cstr_find_from(ss, 0, "brown");
- printf("%" PRIuMAX " [%s]\n", pos, pos == cstr_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_new("hell😀 w😀rl🐨");
- csview ch1 = cstr_at(&s1, 10);
- csview ch2 = cstr_at_u8(&s1, 10);
- printf("ch1: %" c_PRIsv "\n", c_ARGsv(ch1));
- printf("ch2: %" c_PRIsv "\n", c_ARGsv(ch2));
- }
-}
+#define i_implement +#include <stc/cstr.h> +#include <stc/csview.h> +#include <stdio.h> + +int main() +{ + c_autovar (cstr ss = cstr_new("The quick brown fox jumps over the lazy dog.JPG"), cstr_drop(&ss)) { + size_t pos = cstr_find_from(ss, 0, "brown"); + printf("%" PRIuMAX " [%s]\n", pos, pos == cstr_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_new("hell😀 w😀rl🐨"); + csview ch1 = cstr_at(&s1, 10); + csview ch2 = cstr_at_u8(&s1, 10); + printf("ch1: %" c_PRIsv "\n", c_ARGsv(ch1)); + printf("ch2: %" c_PRIsv "\n", c_ARGsv(ch2)); + } +} diff --git a/examples/demos.c b/examples/demos.c index 62df82a4..780a4bff 100644 --- a/examples/demos.c +++ b/examples/demos.c @@ -1,229 +1,229 @@ -#define i_implement
-#include <stc/cstr.h>
-
-void stringdemo1()
-{
- printf("\nSTRINGDEMO1\n");
- c_autovar (cstr cs = cstr_new("one-nine-three-seven-five"), cstr_drop(&cs))
- {
- printf("%s.\n", cstr_str(&cs));
-
- cstr_insert(&cs, 3, "-two");
- printf("%s.\n", cstr_str(&cs));
-
- cstr_erase_n(&cs, 7, 5); // -nine
- printf("%s.\n", cstr_str(&cs));
-
- cstr_replace_one(&cs, 0, "seven", "four");
- printf("%s.\n", cstr_str(&cs));
-
- cstr_take(&cs, cstr_from_fmt("%s *** %s", cstr_str(&cs), cstr_str(&cs)));
- printf("%s.\n", cstr_str(&cs));
-
- printf("find \"four\": %s\n", cstr_str(&cs) + cstr_find(cs, "four"));
-
- // reassign:
- cstr_assign(&cs, "one two three four five six seven");
- cstr_append(&cs, " eight");
- printf("append: %s\n", cstr_str(&cs));
- }
-}
-
-#define i_val int64_t
-#define i_tag ix
-#include <stc/cvec.h>
-
-void vectordemo1()
-{
- printf("\nVECTORDEMO1\n");
- c_autovar (cvec_ix bignums = cvec_ix_with_capacity(100), cvec_ix_drop(&bignums))
- {
- cvec_ix_reserve(&bignums, 100);
- for (size_t i = 10; i <= 100; i += 10)
- cvec_ix_push_back(&bignums, i * i);
-
- printf("erase - %d: %" PRIuMAX "\n", 3, bignums.data[3]);
- cvec_ix_erase_n(&bignums, 3, 1); // erase index 3
-
- cvec_ix_pop_back(&bignums); // erase the last
- cvec_ix_erase_n(&bignums, 0, 1); // erase the first
-
- for (size_t i = 0; i < cvec_ix_size(bignums); ++i) {
- printf("%" PRIuMAX ": %" PRIuMAX "\n", i, bignums.data[i]);
- }
- }
-}
-
-#define i_val_str
-#include <stc/cvec.h>
-
-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));
- }
-}
-
-#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);
- }
-}
-
-#define i_key int
-#define i_tag i
-#include <stc/cset.h>
-
-void setdemo1()
-{
- printf("\nSETDEMO1\n");
- cset_i nums = cset_i_init();
- cset_i_insert(&nums, 8);
- cset_i_insert(&nums, 11);
-
- c_foreach (i, cset_i, nums)
- printf("set: %d\n", *i.ref);
- cset_i_drop(&nums);
-}
-
-#define i_key int
-#define i_val int
-#define i_tag ii
-#include <stc/cmap.h>
-
-void mapdemo1()
-{
- printf("\nMAPDEMO1\n");
- cmap_ii nums = cmap_ii_init();
- cmap_ii_insert(&nums, 8, 64);
- cmap_ii_insert(&nums, 11, 121);
- printf("val 8: %d\n", *cmap_ii_at(&nums, 8));
- cmap_ii_drop(&nums);
-}
-
-#define i_key_str
-#define i_val int
-#define i_tag si
-#include <stc/cmap.h>
-
-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_end(&nums).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);
- }
-}
-
-#define i_key_str
-#define i_val_str
-#include <stc/cmap.h>
-
-void mapdemo3()
-{
- printf("\nMAPDEMO3\n");
- cmap_str table = cmap_str_init();
- cmap_str_emplace(&table, "Map", "test");
- cmap_str_emplace(&table, "Make", "my");
- cmap_str_emplace(&table, "Sunny", "day");
- cmap_str_iter it = cmap_str_find(&table, "Make");
- c_foreach (i, cmap_str, table)
- printf("entry: %s: %s\n", cstr_str(&i.ref->first), cstr_str(&i.ref->second));
- printf("size %" PRIuMAX ": remove: Make: %s\n", cmap_str_size(table), cstr_str(&it.ref->second));
- //cmap_str_erase(&table, "Make");
- cmap_str_erase_at(&table, it);
-
- printf("size %" PRIuMAX "\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.
-}
-
-#define i_val float
-#define i_tag f
-#include <stc/carr3.h>
-
-void arraydemo1()
-{
- printf("\nARRAYDEMO1\n");
- c_autovar (carr3_f arr3 = carr3_f_with_size(30, 20, 10, 0.0f),
- carr3_f_drop(&arr3))
- {
- arr3.data[5][4][3] = 10.2f;
- float **arr2 = arr3.data[5];
- float *arr1 = arr3.data[5][4];
-
- printf("arr3: %" PRIuMAX ": (%" PRIuMAX ", %" PRIuMAX ", %" PRIuMAX ") = %" PRIuMAX "\n", sizeof(arr3),
- arr3.xdim, arr3.ydim, arr3.zdim, carr3_f_size(arr3));
-
- printf("%g\n", arr1[3]); // = 10.2
- printf("%g\n", arr2[4][3]); // = 10.2
- printf("%g\n", arr3.data[5][4][3]); // = 10.2
-
- float x = 0.0;
- c_foreach (i, carr3_f, arr3)
- *i.ref = ++x;
- printf("%g\n", arr3.data[29][19][9]); // = 6000
- }
-}
-
-
-int main()
-{
- stringdemo1();
- vectordemo1();
- vectordemo2();
- listdemo1();
- setdemo1();
- mapdemo1();
- mapdemo2();
- mapdemo3();
- arraydemo1();
-}
+#define i_implement +#include <stc/cstr.h> + +void stringdemo1() +{ + printf("\nSTRINGDEMO1\n"); + c_autovar (cstr cs = cstr_new("one-nine-three-seven-five"), cstr_drop(&cs)) + { + printf("%s.\n", cstr_str(&cs)); + + cstr_insert(&cs, 3, "-two"); + printf("%s.\n", cstr_str(&cs)); + + cstr_erase_n(&cs, 7, 5); // -nine + printf("%s.\n", cstr_str(&cs)); + + cstr_replace_one(&cs, 0, "seven", "four"); + printf("%s.\n", cstr_str(&cs)); + + cstr_take(&cs, cstr_from_fmt("%s *** %s", cstr_str(&cs), cstr_str(&cs))); + printf("%s.\n", cstr_str(&cs)); + + printf("find \"four\": %s\n", cstr_str(&cs) + cstr_find(cs, "four")); + + // reassign: + cstr_assign(&cs, "one two three four five six seven"); + cstr_append(&cs, " eight"); + printf("append: %s\n", cstr_str(&cs)); + } +} + +#define i_val int64_t +#define i_tag ix +#include <stc/cvec.h> + +void vectordemo1() +{ + printf("\nVECTORDEMO1\n"); + c_autovar (cvec_ix bignums = cvec_ix_with_capacity(100), cvec_ix_drop(&bignums)) + { + cvec_ix_reserve(&bignums, 100); + for (size_t i = 10; i <= 100; i += 10) + cvec_ix_push_back(&bignums, i * i); + + printf("erase - %d: %" PRIuMAX "\n", 3, bignums.data[3]); + cvec_ix_erase_n(&bignums, 3, 1); // erase index 3 + + cvec_ix_pop_back(&bignums); // erase the last + cvec_ix_erase_n(&bignums, 0, 1); // erase the first + + for (size_t i = 0; i < cvec_ix_size(bignums); ++i) { + printf("%" PRIuMAX ": %" PRIuMAX "\n", i, bignums.data[i]); + } + } +} + +#define i_val_str +#include <stc/cvec.h> + +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)); + } +} + +#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); + } +} + +#define i_key int +#define i_tag i +#include <stc/cset.h> + +void setdemo1() +{ + printf("\nSETDEMO1\n"); + cset_i nums = cset_i_init(); + cset_i_insert(&nums, 8); + cset_i_insert(&nums, 11); + + c_foreach (i, cset_i, nums) + printf("set: %d\n", *i.ref); + cset_i_drop(&nums); +} + +#define i_key int +#define i_val int +#define i_tag ii +#include <stc/cmap.h> + +void mapdemo1() +{ + printf("\nMAPDEMO1\n"); + cmap_ii nums = cmap_ii_init(); + cmap_ii_insert(&nums, 8, 64); + cmap_ii_insert(&nums, 11, 121); + printf("val 8: %d\n", *cmap_ii_at(&nums, 8)); + cmap_ii_drop(&nums); +} + +#define i_key_str +#define i_val int +#define i_tag si +#include <stc/cmap.h> + +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_end(&nums).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); + } +} + +#define i_key_str +#define i_val_str +#include <stc/cmap.h> + +void mapdemo3() +{ + printf("\nMAPDEMO3\n"); + cmap_str table = cmap_str_init(); + cmap_str_emplace(&table, "Map", "test"); + cmap_str_emplace(&table, "Make", "my"); + cmap_str_emplace(&table, "Sunny", "day"); + cmap_str_iter it = cmap_str_find(&table, "Make"); + c_foreach (i, cmap_str, table) + printf("entry: %s: %s\n", cstr_str(&i.ref->first), cstr_str(&i.ref->second)); + printf("size %" PRIuMAX ": remove: Make: %s\n", cmap_str_size(table), cstr_str(&it.ref->second)); + //cmap_str_erase(&table, "Make"); + cmap_str_erase_at(&table, it); + + printf("size %" PRIuMAX "\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. +} + +#define i_val float +#define i_tag f +#include <stc/carr3.h> + +void arraydemo1() +{ + printf("\nARRAYDEMO1\n"); + c_autovar (carr3_f arr3 = carr3_f_with_size(30, 20, 10, 0.0f), + carr3_f_drop(&arr3)) + { + arr3.data[5][4][3] = 10.2f; + float **arr2 = arr3.data[5]; + float *arr1 = arr3.data[5][4]; + + printf("arr3: %" PRIuMAX ": (%" PRIuMAX ", %" PRIuMAX ", %" PRIuMAX ") = %" PRIuMAX "\n", sizeof(arr3), + arr3.xdim, arr3.ydim, arr3.zdim, carr3_f_size(arr3)); + + printf("%g\n", arr1[3]); // = 10.2 + printf("%g\n", arr2[4][3]); // = 10.2 + printf("%g\n", arr3.data[5][4][3]); // = 10.2 + + float x = 0.0; + c_foreach (i, carr3_f, arr3) + *i.ref = ++x; + printf("%g\n", arr3.data[29][19][9]); // = 6000 + } +} + + +int main() +{ + stringdemo1(); + vectordemo1(); + vectordemo2(); + listdemo1(); + setdemo1(); + mapdemo1(); + mapdemo2(); + mapdemo3(); + arraydemo1(); +} diff --git a/examples/gauss1.c b/examples/gauss1.c index cca38953..75d5567e 100644 --- a/examples/gauss1.c +++ b/examples/gauss1.c @@ -1,57 +1,57 @@ -#include <time.h>
-#include <math.h>
-
-#define STC_IMPLEMENT
-#include <stc/crandom.h>
-#include <stc/cstr.h>
-
-// Declare int -> int hashmap. Uses typetag 'ii' for ints.
-#define i_key int
-#define i_val int
-#define i_tag ii
-#include <stc/cmap.h>
-
-// Declare int vector with entries from the cmap.
-#define i_val cmap_ii_raw
-#define i_less(x, y) x->first < y->first
-#define i_tag ii
-#include <stc/cvec.h>
-
-int main()
-{
- enum {N = 10000000};
- const double Mean = -12.0, StdDev = 6.0, Scale = 74;
-
- printf("Demo of gaussian / normal distribution of %d random samples\n", N);
-
- // Setup random engine with normal distribution.
- uint64_t seed = time(NULL);
- stc64_t rng = stc64_new(seed);
- 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;
- }
-
- // Transfer map to vec and sort it by map keys.
- c_foreach (i, cmap_ii, histmap)
- cvec_ii_push_back(&histvec, (cmap_ii_raw){i.ref->first, i.ref->second});
-
- cvec_ii_sort(&histvec);
-
- // Print the gaussian bar chart
- c_auto (cstr, bar)
- c_foreach (i, cvec_ii, histvec) {
- size_t n = (size_t) (i.ref->second * StdDev * Scale * 2.5 / (float)N);
- if (n > 0) {
- cstr_resize(&bar, n, '*');
- printf("%4d %s\n", i.ref->first, cstr_str(&bar));
- }
- }
- }
-}
+#include <time.h> +#include <math.h> + +#define STC_IMPLEMENT +#include <stc/crandom.h> +#include <stc/cstr.h> + +// Declare int -> int hashmap. Uses typetag 'ii' for ints. +#define i_key int +#define i_val int +#define i_tag ii +#include <stc/cmap.h> + +// Declare int vector with entries from the cmap. +#define i_val cmap_ii_raw +#define i_less(x, y) x->first < y->first +#define i_tag ii +#include <stc/cvec.h> + +int main() +{ + enum {N = 10000000}; + const double Mean = -12.0, StdDev = 6.0, Scale = 74; + + printf("Demo of gaussian / normal distribution of %d random samples\n", N); + + // Setup random engine with normal distribution. + uint64_t seed = time(NULL); + stc64_t rng = stc64_new(seed); + 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; + } + + // Transfer map to vec and sort it by map keys. + c_foreach (i, cmap_ii, histmap) + cvec_ii_push_back(&histvec, (cmap_ii_raw){i.ref->first, i.ref->second}); + + cvec_ii_sort(&histvec); + + // Print the gaussian bar chart + c_auto (cstr, bar) + c_foreach (i, cvec_ii, histvec) { + size_t n = (size_t) (i.ref->second * StdDev * Scale * 2.5 / (float)N); + if (n > 0) { + cstr_resize(&bar, n, '*'); + printf("%4d %s\n", i.ref->first, cstr_str(&bar)); + } + } + } +} diff --git a/examples/gauss2.c b/examples/gauss2.c index 297b8616..2e07c5a5 100644 --- a/examples/gauss2.c +++ b/examples/gauss2.c @@ -1,43 +1,43 @@ -#include <stdio.h>
-#include <time.h>
-
-#define STC_IMPLEMENT
-#include <stc/crandom.h>
-#include <stc/cstr.h>
-
-// Declare int -> int sorted map.
-#define i_key int
-#define i_val size_t
-#include <stc/csmap.h>
-
-int main()
-{
- enum {N = 10000000};
- const double Mean = -12.0, StdDev = 6.0, Scale = 74;
-
- printf("Demo of gaussian / normal distribution of %d random samples\n", N);
-
- // Setup random engine with normal distribution.
- uint64_t seed = time(NULL);
- stc64_t rng = stc64_new(seed);
- 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;
- }
-
- // Print the gaussian bar chart
- c_auto (cstr, bar)
- c_forpair (index, count, csmap_int, mhist) {
- size_t n = (size_t) (*_.count * StdDev * Scale * 2.5 / (float)N);
- if (n > 0) {
- cstr_resize(&bar, n, '*');
- printf("%4d %s\n", *_.index, cstr_str(&bar));
- }
- }
- }
-}
+#include <stdio.h> +#include <time.h> + +#define STC_IMPLEMENT +#include <stc/crandom.h> +#include <stc/cstr.h> + +// Declare int -> int sorted map. +#define i_key int +#define i_val size_t +#include <stc/csmap.h> + +int main() +{ + enum {N = 10000000}; + const double Mean = -12.0, StdDev = 6.0, Scale = 74; + + printf("Demo of gaussian / normal distribution of %d random samples\n", N); + + // Setup random engine with normal distribution. + uint64_t seed = time(NULL); + stc64_t rng = stc64_new(seed); + 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; + } + + // Print the gaussian bar chart + c_auto (cstr, bar) + c_forpair (index, count, csmap_int, mhist) { + size_t n = (size_t) (*_.count * StdDev * Scale * 2.5 / (float)N); + if (n > 0) { + cstr_resize(&bar, n, '*'); + printf("%4d %s\n", *_.index, cstr_str(&bar)); + } + } + } +} diff --git a/examples/hashmap.c b/examples/hashmap.c index 62f20079..ab980045 100644 --- a/examples/hashmap.c +++ b/examples/hashmap.c @@ -1,49 +1,49 @@ -// https://doc.rust-lang.org/rust-by-example/std/hash.html
-#define i_implement
-#include <stc/cstr.h>
-#define i_key_str
-#define i_val_str
-#include <stdio.h>
-#include <stc/cmap.h>
-
-const char* call(const char* number) {
- if (!strcmp(number, "798-1364"))
- return "We're sorry, the call cannot be completed as dialed."
- " Please hang up and try again.";
- else if (!strcmp(number, "645-7689"))
- return "Hello, this is Mr. Awesome's Pizza. My name is Fred."
- " What can I get for you today?";
- else
- return "Hi! Who is this again?";
-}
-
-int main(void) {
- 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(&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("");
- }
-}
+// https://doc.rust-lang.org/rust-by-example/std/hash.html +#define i_implement +#include <stc/cstr.h> +#define i_key_str +#define i_val_str +#include <stdio.h> +#include <stc/cmap.h> + +const char* call(const char* number) { + if (!strcmp(number, "798-1364")) + return "We're sorry, the call cannot be completed as dialed." + " Please hang up and try again."; + else if (!strcmp(number, "645-7689")) + return "Hello, this is Mr. Awesome's Pizza. My name is Fred." + " What can I get for you today?"; + else + return "Hi! Who is this again?"; +} + +int main(void) { + 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(&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(""); + } +} diff --git a/examples/inits.c b/examples/inits.c index 26f4b286..1013da36 100644 --- a/examples/inits.c +++ b/examples/inits.c @@ -1,114 +1,114 @@ -#define i_implement
-#include <stc/cstr.h>
-
-#define i_key int
-#define i_val_str
-#define i_tag id // Map of int => cstr
-#include <stc/cmap.h>
-
-#define i_key_str
-#define i_val int
-#define i_tag cnt // Map of cstr => int
-#include <stc/cmap.h>
-
-typedef struct {int x, y;} ipair_t;
-inline static int ipair_cmp(const ipair_t* a, const ipair_t* b) {
- int c = c_default_cmp(&a->x, &b->x);
- return c ? c : c_default_cmp(&a->y, &b->y);
-}
-
-
-#define i_val ipair_t
-#define i_cmp ipair_cmp
-#define i_tag ip
-#include <stc/cvec.h>
-
-#define i_val ipair_t
-#define i_cmp ipair_cmp
-#define i_tag ip
-#define i_extern // define _clist_mergesort() once
-#include <stc/clist.h>
-
-#define i_val float
-#define i_tag f
-#include <stc/cpque.h>
-
-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_apply_arr(v, cpque_f_push(&floats, *v), const float, nums, c_arraylen(nums));
-
- puts("\npop and show high priorites first:");
- while (! cpque_f_empty(floats)) {
- printf("%.1f ", *cpque_f_top(&floats));
- cpque_f_pop(&floats);
- }
- puts("\n");
- }
-
- // CMAP ID
-
- int year = 2020;
- c_auto (cmap_id, idnames) {
- cmap_id_emplace(&idnames, 100, "Hello");
- cmap_id_insert(&idnames, 110, cstr_new("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 CNT
-
- c_auto (cmap_cnt, countries) {
- c_apply(v, cmap_cnt_emplace(&countries, c_pair(v)), cmap_cnt_raw, {
- {"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("");
- }
-
- // CVEC PAIR
-
- c_auto (cvec_ip, pairs1) {
- c_apply(p, cvec_ip_push_back(&pairs1, *p), ipair_t,
- {{5, 6}, {3, 4}, {1, 2}, {7, 8}});
- cvec_ip_sort(&pairs1);
-
- c_foreach (i, cvec_ip, pairs1)
- printf("(%d %d) ", i.ref->x, i.ref->y);
- puts("");
- }
-
- // CLIST PAIR
-
- c_auto (clist_ip, pairs2) {
- c_apply(p, clist_ip_push_back(&pairs2, *p), ipair_t,
- {{5, 6}, {3, 4}, {1, 2}, {7, 8}});
- clist_ip_sort(&pairs2);
-
- c_foreach (i, clist_ip, pairs2)
- printf("(%d %d) ", i.ref->x, i.ref->y);
- puts("");
- }
-}
+#define i_implement +#include <stc/cstr.h> + +#define i_key int +#define i_val_str +#define i_tag id // Map of int => cstr +#include <stc/cmap.h> + +#define i_key_str +#define i_val int +#define i_tag cnt // Map of cstr => int +#include <stc/cmap.h> + +typedef struct {int x, y;} ipair_t; +inline static int ipair_cmp(const ipair_t* a, const ipair_t* b) { + int c = c_default_cmp(&a->x, &b->x); + return c ? c : c_default_cmp(&a->y, &b->y); +} + + +#define i_val ipair_t +#define i_cmp ipair_cmp +#define i_tag ip +#include <stc/cvec.h> + +#define i_val ipair_t +#define i_cmp ipair_cmp +#define i_tag ip +#define i_extern // define _clist_mergesort() once +#include <stc/clist.h> + +#define i_val float +#define i_tag f +#include <stc/cpque.h> + +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_apply_arr(v, cpque_f_push(&floats, *v), const float, nums, c_arraylen(nums)); + + puts("\npop and show high priorites first:"); + while (! cpque_f_empty(floats)) { + printf("%.1f ", *cpque_f_top(&floats)); + cpque_f_pop(&floats); + } + puts("\n"); + } + + // CMAP ID + + int year = 2020; + c_auto (cmap_id, idnames) { + cmap_id_emplace(&idnames, 100, "Hello"); + cmap_id_insert(&idnames, 110, cstr_new("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 CNT + + c_auto (cmap_cnt, countries) { + c_apply(v, cmap_cnt_emplace(&countries, c_pair(v)), cmap_cnt_raw, { + {"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(""); + } + + // CVEC PAIR + + c_auto (cvec_ip, pairs1) { + c_apply(p, cvec_ip_push_back(&pairs1, *p), ipair_t, + {{5, 6}, {3, 4}, {1, 2}, {7, 8}}); + cvec_ip_sort(&pairs1); + + c_foreach (i, cvec_ip, pairs1) + printf("(%d %d) ", i.ref->x, i.ref->y); + puts(""); + } + + // CLIST PAIR + + c_auto (clist_ip, pairs2) { + c_apply(p, clist_ip_push_back(&pairs2, *p), ipair_t, + {{5, 6}, {3, 4}, {1, 2}, {7, 8}}); + clist_ip_sort(&pairs2); + + c_foreach (i, clist_ip, pairs2) + printf("(%d %d) ", i.ref->x, i.ref->y); + puts(""); + } +} diff --git a/examples/list.c b/examples/list.c index 7d6d1a50..17ed048d 100644 --- a/examples/list.c +++ b/examples/list.c @@ -1,61 +1,61 @@ -#include <stdio.h>
-#include <time.h>
-
-#define STC_IMPLEMENT
-#define STC_EXTERN
-
-#define i_val double
-#define i_tag fx
-#include <stc/clist.h>
-#include <stc/crandom.h>
-
-int main() {
- int k;
- const int n = 2000000;
-
- c_auto (clist_fx, list)
- {
- stc64_t rng = stc64_new(1234);
- stc64_uniformf_t dist = stc64_uniformf_new(100.0f, n);
- int m = 0;
- c_forrange (i, int, n)
- clist_fx_push_back(&list, stc64_uniformf(&rng, &dist)), ++m;
- double sum = 0.0;
- printf("sumarize %d:\n", m);
- c_foreach (i, clist_fx, list)
- sum += *i.ref;
- printf("sum %f\n\n", sum);
-
- k = 0;
- c_foreach (i, clist_fx, list)
- if (++k <= 10) printf("%8d: %10f\n", k, *i.ref); else break;
- puts("sort");
- clist_fx_sort(&list); // mergesort O(n*log n)
- puts("sorted");
-
- k = 0;
- c_foreach (i, clist_fx, list)
- if (++k <= 10) printf("%8d: %10f\n", k, *i.ref); else break;
- puts("");
-
- clist_fx_clear(&list);
- c_apply(v, clist_fx_push_back(&list, *v), int, {10, 20, 30, 40, 30, 50});
- const double* v = clist_fx_get(&list, 30);
- printf("found: %f\n", *v);
- c_foreach (i, clist_fx, 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);
- clist_fx_iter it = clist_fx_begin(&list);
- printf("Full: ");
- c_foreach (i, clist_fx, list)
- printf(" %g", *i.ref);
- printf("\nSubs: ");
- c_foreach (i, clist_fx, clist_fx_advance(it, 4), clist_fx_end(&list))
- printf(" %g", *i.ref);
- puts("");
- }
-}
+#include <stdio.h> +#include <time.h> + +#define STC_IMPLEMENT +#define STC_EXTERN + +#define i_val double +#define i_tag fx +#include <stc/clist.h> +#include <stc/crandom.h> + +int main() { + int k; + const int n = 2000000; + + c_auto (clist_fx, list) + { + stc64_t rng = stc64_new(1234); + stc64_uniformf_t dist = stc64_uniformf_new(100.0f, n); + int m = 0; + c_forrange (i, int, n) + clist_fx_push_back(&list, stc64_uniformf(&rng, &dist)), ++m; + double sum = 0.0; + printf("sumarize %d:\n", m); + c_foreach (i, clist_fx, list) + sum += *i.ref; + printf("sum %f\n\n", sum); + + k = 0; + c_foreach (i, clist_fx, list) + if (++k <= 10) printf("%8d: %10f\n", k, *i.ref); else break; + puts("sort"); + clist_fx_sort(&list); // mergesort O(n*log n) + puts("sorted"); + + k = 0; + c_foreach (i, clist_fx, list) + if (++k <= 10) printf("%8d: %10f\n", k, *i.ref); else break; + puts(""); + + clist_fx_clear(&list); + c_apply(v, clist_fx_push_back(&list, *v), int, {10, 20, 30, 40, 30, 50}); + const double* v = clist_fx_get(&list, 30); + printf("found: %f\n", *v); + c_foreach (i, clist_fx, 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); + clist_fx_iter it = clist_fx_begin(&list); + printf("Full: "); + c_foreach (i, clist_fx, list) + printf(" %g", *i.ref); + printf("\nSubs: "); + c_foreach (i, clist_fx, clist_fx_advance(it, 4), clist_fx_end(&list)) + printf(" %g", *i.ref); + puts(""); + } +} diff --git a/examples/list_erase.c b/examples/list_erase.c index 19a00299..ad062131 100644 --- a/examples/list_erase.c +++ b/examples/list_erase.c @@ -1,29 +1,29 @@ -// erasing from clist
-#include <stdio.h>
-
-#define i_val int
-#include <stc/clist.h>
-
-int main ()
-{
- c_auto (clist_int, L)
- {
- c_apply(i, clist_int_push_back(&L, *i), int, {10, 20, 30, 40, 50});
- c_foreach (x, clist_int, L)
- printf("%d ", *x.ref);
- puts("");
- // 10 20 30 40 50
- clist_int_iter it = clist_int_begin(&L); // ^
- clist_int_next(&it);
- it = clist_int_erase_at(&L, it); // 10 30 40 50
- // ^
- clist_int_iter end = clist_int_end(&L); //
- clist_int_next(&it);
- it = clist_int_erase_range(&L, it, end); // 10 30
- // ^
- printf("list contains:");
- c_foreach (x, clist_int, L)
- printf(" %d", *x.ref);
- puts("");
- }
-}
+// erasing from clist +#include <stdio.h> + +#define i_val int +#include <stc/clist.h> + +int main () +{ + c_auto (clist_int, L) + { + c_apply(i, clist_int_push_back(&L, *i), int, {10, 20, 30, 40, 50}); + c_foreach (x, clist_int, L) + printf("%d ", *x.ref); + puts(""); + // 10 20 30 40 50 + clist_int_iter it = clist_int_begin(&L); // ^ + clist_int_next(&it); + it = clist_int_erase_at(&L, it); // 10 30 40 50 + // ^ + clist_int_iter end = clist_int_end(&L); // + clist_int_next(&it); + it = clist_int_erase_range(&L, it, end); // 10 30 + // ^ + printf("list contains:"); + c_foreach (x, clist_int, L) + printf(" %d", *x.ref); + puts(""); + } +} diff --git a/examples/lower_bound.c b/examples/lower_bound.c index 6039dd48..a1de1cfd 100644 --- a/examples/lower_bound.c +++ b/examples/lower_bound.c @@ -1,64 +1,64 @@ -#include <stdio.h>
-
-#define i_val int
-#include <stc/cvec.h>
-
-#define i_val int
-#include <stc/csset.h>
-
-int main()
-{
- // TEST SORTED VECTOR
- c_auto (cvec_int, vec)
- {
- int key, *res;
-
- c_apply(t, cvec_int_push(&vec, *t), int, {
- 40, 600, 1, 7000, 2, 500, 30,
- });
-
- cvec_int_sort(&vec);
-
- key = 500;
- res = cvec_int_lower_bound(&vec, key).ref;
- if (res != cvec_int_end(&vec).ref)
- printf("Sorted Vec %d: lower bound: %d\n", key, *res); // 600
-
- key = 550;
- res = cvec_int_lower_bound(&vec, key).ref;
- if (res != cvec_int_end(&vec).ref)
- printf("Sorted Vec %d: lower_bound: %d\n", key, *res); // 500
-
- key = 500;
- res = cvec_int_binary_search(&vec, key).ref;
- if (res != cvec_int_end(&vec).ref)
- printf("Sorted Vec %d: bin. search: %d\n", key, *res); // 500
- puts("");
- }
-
- // TEST SORTED SET
- c_auto (csset_int, set)
- {
- int key, *res;
-
- c_apply(t, csset_int_push(&set, *t), int, {
- 40, 600, 1, 7000, 2, 500, 30,
- });
-
- key = 500;
- res = csset_int_lower_bound(&set, key).ref;
- if (res != csset_int_end(&set).ref)
- printf("Sorted Set %d: lower bound: %d\n", key, *res); // 600
-
- key = 550;
- res = csset_int_lower_bound(&set, key).ref;
- if (res != csset_int_end(&set).ref)
- printf("Sorted Set %d: lower bound: %d\n", key, *res); // 600
-
- key = 500;
- res = csset_int_find(&set, key).ref;
- if (res != csset_int_end(&set).ref)
- printf("Sorted Set %d: find : %d\n", key, *res); // 600
- }
- return 0;
-}
+#include <stdio.h> + +#define i_val int +#include <stc/cvec.h> + +#define i_val int +#include <stc/csset.h> + +int main() +{ + // TEST SORTED VECTOR + c_auto (cvec_int, vec) + { + int key, *res; + + c_apply(t, cvec_int_push(&vec, *t), int, { + 40, 600, 1, 7000, 2, 500, 30, + }); + + cvec_int_sort(&vec); + + key = 500; + res = cvec_int_lower_bound(&vec, key).ref; + if (res != cvec_int_end(&vec).ref) + printf("Sorted Vec %d: lower bound: %d\n", key, *res); // 600 + + key = 550; + res = cvec_int_lower_bound(&vec, key).ref; + if (res != cvec_int_end(&vec).ref) + printf("Sorted Vec %d: lower_bound: %d\n", key, *res); // 500 + + key = 500; + res = cvec_int_binary_search(&vec, key).ref; + if (res != cvec_int_end(&vec).ref) + printf("Sorted Vec %d: bin. search: %d\n", key, *res); // 500 + puts(""); + } + + // TEST SORTED SET + c_auto (csset_int, set) + { + int key, *res; + + c_apply(t, csset_int_push(&set, *t), int, { + 40, 600, 1, 7000, 2, 500, 30, + }); + + key = 500; + res = csset_int_lower_bound(&set, key).ref; + if (res != csset_int_end(&set).ref) + printf("Sorted Set %d: lower bound: %d\n", key, *res); // 600 + + key = 550; + res = csset_int_lower_bound(&set, key).ref; + if (res != csset_int_end(&set).ref) + printf("Sorted Set %d: lower bound: %d\n", key, *res); // 600 + + key = 500; + res = csset_int_find(&set, key).ref; + if (res != csset_int_end(&set).ref) + printf("Sorted Set %d: find : %d\n", key, *res); // 600 + } + return 0; +} diff --git a/examples/mapmap.c b/examples/mapmap.c index 9ac22371..ab48ecc6 100644 --- a/examples/mapmap.c +++ b/examples/mapmap.c @@ -1,73 +1,73 @@ -// unordered_map<string, unordered_map<string, string>>:
-#define i_implement
-#include <stc/cstr.h>
-#define i_type People
-#define i_key_str
-#define i_val_str
-#define i_keydrop(p) (printf("kdrop: %s\n", cstr_str(p)), cstr_drop(p)) // override
-#include <stc/csmap.h>
-
-#define i_type Departments
-#define i_key_str
-#define i_val_bind People
-// Shorthand for:
-// #define i_val People
-// #define i_cmp People_cmp
-// #define i_valclone People_clone
-// #define i_valdrop People_drop
-#include <stc/csmap.h>
-
-#define i_type Stack
-#define i_val_bind People_value
-// Shorthand for:
-// #define i_val People_value (pair of cstr)
-// #define i_cmp People_value_cmp
-// #define i_valclone People_value_clone
-// #define i_valdrop People_value_drop
-#include <stc/cvec.h>
-
-void add(Departments* deps, const char* name, const char* email, const char* dep)
-{
- People *people = &Departments_insert(deps, cstr_from(dep), People_init()).ref->second;
- People_emplace_or_assign(people, name, email);
-}
-
-int contains(Departments* map, const char* name)
-{
- int count = 0;
- c_foreach (i, Departments, *map)
- if (People_contains(&i.ref->second, name))
- ++count;
- return count;
-}
-
-int main(void)
-{
- 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");
-
- 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: %d\n", contains(&map, "Nick Denton"));
- printf("found: %d\n", contains(&map, "Patrick Dust"));
- printf("found: %d\n", contains(&map, "Dennis Kay"));
- printf("found: %d\n", contains(&map, "Serena Bath"));
- puts("Done");
- }
-}
+// unordered_map<string, unordered_map<string, string>>: +#define i_implement +#include <stc/cstr.h> +#define i_type People +#define i_key_str +#define i_val_str +#define i_keydrop(p) (printf("kdrop: %s\n", cstr_str(p)), cstr_drop(p)) // override +#include <stc/csmap.h> + +#define i_type Departments +#define i_key_str +#define i_val_bind People +// Shorthand for: +// #define i_val People +// #define i_cmp People_cmp +// #define i_valclone People_clone +// #define i_valdrop People_drop +#include <stc/csmap.h> + +#define i_type Stack +#define i_val_bind People_value +// Shorthand for: +// #define i_val People_value (pair of cstr) +// #define i_cmp People_value_cmp +// #define i_valclone People_value_clone +// #define i_valdrop People_value_drop +#include <stc/cvec.h> + +void add(Departments* deps, const char* name, const char* email, const char* dep) +{ + People *people = &Departments_insert(deps, cstr_from(dep), People_init()).ref->second; + People_emplace_or_assign(people, name, email); +} + +int contains(Departments* map, const char* name) +{ + int count = 0; + c_foreach (i, Departments, *map) + if (People_contains(&i.ref->second, name)) + ++count; + return count; +} + +int main(void) +{ + 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"); + + 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: %d\n", contains(&map, "Nick Denton")); + printf("found: %d\n", contains(&map, "Patrick Dust")); + printf("found: %d\n", contains(&map, "Dennis Kay")); + printf("found: %d\n", contains(&map, "Serena Bath")); + puts("Done"); + } +} diff --git a/examples/mmap.c b/examples/mmap.c index cfb7470e..5e3eda00 100644 --- a/examples/mmap.c +++ b/examples/mmap.c @@ -1,76 +1,76 @@ -// This implements the multimap c++ example found at:
-// https://en.cppreference.com/w/cpp/container/multimap/insert
-
-// Multimap entries
-#define i_implement
-#include <stc/cstr.h>
-#define i_val_str
-#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_val_bind clist_str // uses clist_str as i_val and binds clist_str_clone, clist_str_drop
-#define i_cmp -c_default_cmp // like std::greater<int>
-#include <stc/csmap.h>
-
-void print(const char* lbl, const Multimap mmap)
-{
- printf("%s ", lbl);
- c_foreach (e, Multimap, mmap) {
- c_foreach (s, clist_str, e.ref->second)
- printf("{%d,%s} ", e.ref->first, cstr_str(s.ref));
- }
- puts("");
-}
-
-void insert(Multimap* mmap, int key, const char* str)
-{
- clist_str *list = &Multimap_insert(mmap, key, clist_str_init()).ref->second;
- clist_str_emplace_back(list, str);
-}
-
-int main()
-{
- c_auto (Multimap, mmap)
- {
- // list-initialize
- struct { int first; const char* second; } vals[] =
- {{2, "foo"}, {2, "bar"}, {3, "baz"}, {1, "abc"}, {5, "def"}};
- c_forrange (i, c_arraylen(vals)) insert(&mmap, c_pair(&vals[i]));
- print("#1", mmap);
-
- // insert using value_type
- insert(&mmap, 5, "pqr");
- print("#2", mmap);
-
- // insert using make_pair
- insert(&mmap, 6, "uvw");
- print("#3", mmap);
-
- insert(&mmap, 7, "xyz");
- print("#4", mmap);
-
- // insert using initialization_list
- insert(&mmap, 5, "one");
- insert(&mmap, 5, "two");
- print("#5", mmap);
-
- // FOLLOWING NOT IN ORIGINAL EXAMPLE:
-
- // erase all entries with key 5
- Multimap_erase(&mmap, 5);
- print("+6", mmap);
-
- // find and erase first entry containing "bar"
- clist_str_iter pos;
- c_foreach (e, Multimap, mmap) {
- if ((pos = clist_str_find(&e.ref->second, "bar")).ref != clist_str_end(&e.ref->second).ref) {
- clist_str_erase_at(&e.ref->second, pos);
- break;
- }
- }
- print("+7", mmap);
- }
-}
+// This implements the multimap c++ example found at: +// https://en.cppreference.com/w/cpp/container/multimap/insert + +// Multimap entries +#define i_implement +#include <stc/cstr.h> +#define i_val_str +#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_val_bind clist_str // uses clist_str as i_val and binds clist_str_clone, clist_str_drop +#define i_cmp -c_default_cmp // like std::greater<int> +#include <stc/csmap.h> + +void print(const char* lbl, const Multimap mmap) +{ + printf("%s ", lbl); + c_foreach (e, Multimap, mmap) { + c_foreach (s, clist_str, e.ref->second) + printf("{%d,%s} ", e.ref->first, cstr_str(s.ref)); + } + puts(""); +} + +void insert(Multimap* mmap, int key, const char* str) +{ + clist_str *list = &Multimap_insert(mmap, key, clist_str_init()).ref->second; + clist_str_emplace_back(list, str); +} + +int main() +{ + c_auto (Multimap, mmap) + { + // list-initialize + struct { int first; const char* second; } vals[] = + {{2, "foo"}, {2, "bar"}, {3, "baz"}, {1, "abc"}, {5, "def"}}; + c_forrange (i, c_arraylen(vals)) insert(&mmap, c_pair(&vals[i])); + print("#1", mmap); + + // insert using value_type + insert(&mmap, 5, "pqr"); + print("#2", mmap); + + // insert using make_pair + insert(&mmap, 6, "uvw"); + print("#3", mmap); + + insert(&mmap, 7, "xyz"); + print("#4", mmap); + + // insert using initialization_list + insert(&mmap, 5, "one"); + insert(&mmap, 5, "two"); + print("#5", mmap); + + // FOLLOWING NOT IN ORIGINAL EXAMPLE: + + // erase all entries with key 5 + Multimap_erase(&mmap, 5); + print("+6", mmap); + + // find and erase first entry containing "bar" + clist_str_iter pos; + c_foreach (e, Multimap, mmap) { + if ((pos = clist_str_find(&e.ref->second, "bar")).ref != clist_str_end(&e.ref->second).ref) { + clist_str_erase_at(&e.ref->second, pos); + break; + } + } + print("+7", mmap); + } +} diff --git a/examples/multimap.c b/examples/multimap.c index c2920ef4..a2d06a06 100644 --- a/examples/multimap.c +++ b/examples/multimap.c @@ -1,100 +1,100 @@ -#define i_implement
-#include <stc/cstr.h>
-
-// Olympics multimap example
-
-struct OlympicsData { int year; const char *city, *country, *date; } ol_data[] = {
- {2026, "Milan and Cortina d'Ampezzo", "Italy", "February 6-22"},
- {2022, "Beijing", "China", "February 4-20"},
- {2018, "PyeongChang", "South Korea", "February 9-25"},
- {2014, "Sochi", "Russia", "February 7-23"},
- {2010, "Vancouver", "Canada", "February 12-28"},
- {2006, "Torino", "Italy", "February 10-26"},
- {2002, "Salt Lake City", "United States", "February 8-24"},
- {1998, "Nagano", "Japan", "February 7-22"},
- {1994, "Lillehammer", "Norway", "February 12-27"},
- {1992, "Albertville", "France", "February 8-23"},
- {1988, "Calgary", "Canada", "February 13-28"},
- {1984, "Sarajevo", "Yugoslavia", "February 8-19"},
- {1980, "Lake Placid", "United States", "February 13-24"},
- {1976, "Innsbruck", "Austria", "February 4-15"},
- {1972, "Sapporo", "Japan", "February 3-13"},
- {1968, "Grenoble", "France", "February 6-18"},
- {1964, "Innsbruck", "Austria", "January 29-February 9"},
- {1960, "Squaw Valley", "United States", "February 18-28"},
- {1956, "Cortina d'Ampezzo", "Italy", "January 26 - February 5"},
- {1952, "Oslo", "Norway", "February 14 - 25"},
- {1948, "St. Moritz", "Switzerland", "January 30 - February 8"},
- {1944, "canceled", "canceled", "canceled"},
- {1940, "canceled", "canceled", "canceled"},
- {1936, "Garmisch-Partenkirchen", "Germany", "February 6 - 16"},
- {1932, "Lake Placid", "United States", "February 4 - 15"},
- {1928, "St. Moritz", "Switzerland", "February 11 - 19"},
- {1924, "Chamonix", "France", "January 25 - February 5"},
-};
-
-typedef struct { int year; cstr city, date; } OlympicLocation;
-
-int OlympicLocation_cmp(const OlympicLocation* a, const OlympicLocation* b);
-OlympicLocation OlympicLocation_clone(OlympicLocation loc);
-void OlympicLocation_drop(OlympicLocation* self);
-
-// Create a clist<OlympicLocation>, can be sorted by year.
-#define i_val_bind OlympicLocation // binds _cmp, _clone and _drop.
-#define i_tag OL
-#define i_extern // define _clist_mergesort()
-#include <stc/clist.h>
-
-// Create a csmap<cstr, clist_OL> where key is country name
-#define i_key_str // binds cstr_equ, cstr_hash, cstr_clone, ++
-#define i_val_bind clist_OL // binds clist_OL_clone, clist_OL_drop
-#define i_tag OL
-#include <stc/csmap.h>
-
-int OlympicLocation_cmp(const OlympicLocation* a, const OlympicLocation* b) {
- return a->year - b->year;
-}
-
-OlympicLocation OlympicLocation_clone(OlympicLocation loc) {
- loc.city = cstr_clone(loc.city);
- loc.date = cstr_clone(loc.date);
- return loc;
-}
-void OlympicLocation_drop(OlympicLocation* self) {
- c_drop(cstr, &self->city, &self->date);
-}
-
-int main()
-{
- // Define the multimap with destructor defered to when block is completed.
- c_auto (csmap_OL, multimap)
- {
- const clist_OL empty = clist_OL_init();
-
- for (size_t i = 0; i < c_arraylen(ol_data); ++i)
- {
- struct OlympicsData* d = &ol_data[i];
- OlympicLocation 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_insert(&multimap, cstr_from(d->country), empty).ref->second;
- clist_OL_push_back(list, loc);
- }
- // Sort locations by year for each country.
- c_foreach (country, csmap_OL, multimap)
- clist_OL_sort(&country.ref->second);
-
- // Print the multimap:
- c_foreach (country, csmap_OL, multimap)
- {
- // Loop the locations for a country sorted by year
- c_foreach (loc, clist_OL, country.ref->second)
- printf("%s: %d, %s, %s\n", cstr_str(&country.ref->first),
- loc.ref->year,
- cstr_str(&loc.ref->city),
- cstr_str(&loc.ref->date));
- }
- }
-}
+#define i_implement +#include <stc/cstr.h> + +// Olympics multimap example + +struct OlympicsData { int year; const char *city, *country, *date; } ol_data[] = { + {2026, "Milan and Cortina d'Ampezzo", "Italy", "February 6-22"}, + {2022, "Beijing", "China", "February 4-20"}, + {2018, "PyeongChang", "South Korea", "February 9-25"}, + {2014, "Sochi", "Russia", "February 7-23"}, + {2010, "Vancouver", "Canada", "February 12-28"}, + {2006, "Torino", "Italy", "February 10-26"}, + {2002, "Salt Lake City", "United States", "February 8-24"}, + {1998, "Nagano", "Japan", "February 7-22"}, + {1994, "Lillehammer", "Norway", "February 12-27"}, + {1992, "Albertville", "France", "February 8-23"}, + {1988, "Calgary", "Canada", "February 13-28"}, + {1984, "Sarajevo", "Yugoslavia", "February 8-19"}, + {1980, "Lake Placid", "United States", "February 13-24"}, + {1976, "Innsbruck", "Austria", "February 4-15"}, + {1972, "Sapporo", "Japan", "February 3-13"}, + {1968, "Grenoble", "France", "February 6-18"}, + {1964, "Innsbruck", "Austria", "January 29-February 9"}, + {1960, "Squaw Valley", "United States", "February 18-28"}, + {1956, "Cortina d'Ampezzo", "Italy", "January 26 - February 5"}, + {1952, "Oslo", "Norway", "February 14 - 25"}, + {1948, "St. Moritz", "Switzerland", "January 30 - February 8"}, + {1944, "canceled", "canceled", "canceled"}, + {1940, "canceled", "canceled", "canceled"}, + {1936, "Garmisch-Partenkirchen", "Germany", "February 6 - 16"}, + {1932, "Lake Placid", "United States", "February 4 - 15"}, + {1928, "St. Moritz", "Switzerland", "February 11 - 19"}, + {1924, "Chamonix", "France", "January 25 - February 5"}, +}; + +typedef struct { int year; cstr city, date; } OlympicLocation; + +int OlympicLocation_cmp(const OlympicLocation* a, const OlympicLocation* b); +OlympicLocation OlympicLocation_clone(OlympicLocation loc); +void OlympicLocation_drop(OlympicLocation* self); + +// Create a clist<OlympicLocation>, can be sorted by year. +#define i_val_bind OlympicLocation // binds _cmp, _clone and _drop. +#define i_tag OL +#define i_extern // define _clist_mergesort() +#include <stc/clist.h> + +// Create a csmap<cstr, clist_OL> where key is country name +#define i_key_str // binds cstr_equ, cstr_hash, cstr_clone, ++ +#define i_val_bind clist_OL // binds clist_OL_clone, clist_OL_drop +#define i_tag OL +#include <stc/csmap.h> + +int OlympicLocation_cmp(const OlympicLocation* a, const OlympicLocation* b) { + return a->year - b->year; +} + +OlympicLocation OlympicLocation_clone(OlympicLocation loc) { + loc.city = cstr_clone(loc.city); + loc.date = cstr_clone(loc.date); + return loc; +} +void OlympicLocation_drop(OlympicLocation* self) { + c_drop(cstr, &self->city, &self->date); +} + +int main() +{ + // Define the multimap with destructor defered to when block is completed. + c_auto (csmap_OL, multimap) + { + const clist_OL empty = clist_OL_init(); + + for (size_t i = 0; i < c_arraylen(ol_data); ++i) + { + struct OlympicsData* d = &ol_data[i]; + OlympicLocation 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_insert(&multimap, cstr_from(d->country), empty).ref->second; + clist_OL_push_back(list, loc); + } + // Sort locations by year for each country. + c_foreach (country, csmap_OL, multimap) + clist_OL_sort(&country.ref->second); + + // Print the multimap: + c_foreach (country, csmap_OL, multimap) + { + // Loop the locations for a country sorted by year + c_foreach (loc, clist_OL, country.ref->second) + printf("%s: %d, %s, %s\n", cstr_str(&country.ref->first), + loc.ref->year, + cstr_str(&loc.ref->city), + cstr_str(&loc.ref->date)); + } + } +} diff --git a/examples/music_arc.c b/examples/music_arc.c index b6b59489..13075741 100644 --- a/examples/music_arc.c +++ b/examples/music_arc.c @@ -1,59 +1,59 @@ -// shared_ptr-examples.cpp
-// based on https://docs.microsoft.com/en-us/cpp/cpp/how-to-create-and-use-shared-ptr-instances?view=msvc-160
-#define i_implement
-#include <stc/cstr.h>
-
-struct Song
-{
- cstr artist;
- cstr title;
-} typedef Song;
-
-Song Song_new(const char* artist, const char* title)
- { return (Song){cstr_from(artist), cstr_from(title)}; }
-
-void Song_drop(Song* s) {
- printf("drop: %s\n", cstr_str(&s->title));
- c_drop(cstr, &s->artist, &s->title);
-}
-
-#define i_type SongPtr
-#define i_val Song
-#define i_valdrop Song_drop
-#define i_opt c_no_cmp
-#include <stc/carc.h>
-
-#define i_type SongVec
-#define i_val_arcbox SongPtr
-#include <stc/cvec.h>
-
-void example3()
-{
- c_auto (SongVec, vec, vec2)
- {
- c_apply(v, SongVec_push_back(&vec, *v), SongPtr, {
- SongPtr_make(Song_new("Bob Dylan", "The Times They Are A Changing")),
- SongPtr_make(Song_new("Aretha Franklin", "Bridge Over Troubled Water")),
- SongPtr_make(Song_new("Thalia", "Entre El Mar y Una Estrella"))
- });
-
- c_foreach (s, SongVec, vec)
- if (!cstr_equals(s.ref->get->artist, "Bob Dylan"))
- SongVec_push_back(&vec2, SongPtr_clone(*s.ref));
-
- c_apply(v, SongVec_push_back(&vec2, *v), SongPtr, {
- SongPtr_make(Song_new("Michael Jackson", "Billie Jean")),
- SongPtr_make(Song_new("Rihanna", "Stay")),
- });
-
- c_foreach (s, SongVec, vec2)
- printf("%s - %s: refs %lu\n", cstr_str(&s.ref->get->artist),
- cstr_str(&s.ref->get->title),
- *s.ref->use_count);
- }
-}
-
-int main()
-{
- example3();
-}
+// shared_ptr-examples.cpp +// based on https://docs.microsoft.com/en-us/cpp/cpp/how-to-create-and-use-shared-ptr-instances?view=msvc-160 +#define i_implement +#include <stc/cstr.h> + +struct Song +{ + cstr artist; + cstr title; +} typedef Song; + +Song Song_new(const char* artist, const char* title) + { return (Song){cstr_from(artist), cstr_from(title)}; } + +void Song_drop(Song* s) { + printf("drop: %s\n", cstr_str(&s->title)); + c_drop(cstr, &s->artist, &s->title); +} + +#define i_type SongPtr +#define i_val Song +#define i_valdrop Song_drop +#define i_opt c_no_cmp +#include <stc/carc.h> + +#define i_type SongVec +#define i_val_arcbox SongPtr +#include <stc/cvec.h> + +void example3() +{ + c_auto (SongVec, vec, vec2) + { + c_apply(v, SongVec_push_back(&vec, *v), SongPtr, { + SongPtr_make(Song_new("Bob Dylan", "The Times They Are A Changing")), + SongPtr_make(Song_new("Aretha Franklin", "Bridge Over Troubled Water")), + SongPtr_make(Song_new("Thalia", "Entre El Mar y Una Estrella")) + }); + + c_foreach (s, SongVec, vec) + if (!cstr_equals(s.ref->get->artist, "Bob Dylan")) + SongVec_push_back(&vec2, SongPtr_clone(*s.ref)); + + c_apply(v, SongVec_push_back(&vec2, *v), SongPtr, { + SongPtr_make(Song_new("Michael Jackson", "Billie Jean")), + SongPtr_make(Song_new("Rihanna", "Stay")), + }); + + c_foreach (s, SongVec, vec2) + printf("%s - %s: refs %lu\n", cstr_str(&s.ref->get->artist), + cstr_str(&s.ref->get->title), + *s.ref->use_count); + } +} + +int main() +{ + example3(); +} diff --git a/examples/new_deq.c b/examples/new_deq.c index f1e872f0..5fe2403a 100644 --- a/examples/new_deq.c +++ b/examples/new_deq.c @@ -1,62 +1,62 @@ -#define i_implement
-#include <stc/cstr.h>
-#include <stc/forward.h>
-
-forward_cdeq(cdeq_i32, int);
-forward_cdeq(cdeq_pnt, struct Point);
-
-struct MyStruct {
- cdeq_i32 intvec;
- cdeq_pnt pntvec;
-} typedef MyStruct;
-
-
-#define i_val int
-#define i_opt c_is_fwd
-#define i_tag i32
-#include <stc/cdeq.h>
-
-struct Point { int x, y; } typedef Point;
-int point_cmp(const Point* a, const Point* b) {
- int c = a->x - b->x;
- return c ? c : a->y - b->y;
-}
-
-#define i_val Point
-#define i_cmp point_cmp
-#define i_opt c_is_fwd
-#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.3);
- }
- 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");
- }
-}
+#define i_implement +#include <stc/cstr.h> +#include <stc/forward.h> + +forward_cdeq(cdeq_i32, int); +forward_cdeq(cdeq_pnt, struct Point); + +struct MyStruct { + cdeq_i32 intvec; + cdeq_pnt pntvec; +} typedef MyStruct; + + +#define i_val int +#define i_opt c_is_fwd +#define i_tag i32 +#include <stc/cdeq.h> + +struct Point { int x, y; } typedef Point; +int point_cmp(const Point* a, const Point* b) { + int c = a->x - b->x; + return c ? c : a->y - b->y; +} + +#define i_val Point +#define i_cmp point_cmp +#define i_opt c_is_fwd +#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.3); + } + 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"); + } +} diff --git a/examples/new_map.c b/examples/new_map.c index 0882d02f..78c1a44d 100644 --- a/examples/new_map.c +++ b/examples/new_map.c @@ -1,73 +1,73 @@ -#define i_implement
-#include <stc/cstr.h>
-#include <stc/forward.h>
-
-forward_cmap(cmap_pnt, struct Point, int);
-
-struct MyStruct {
- cmap_pnt pntmap;
- cstr name;
-} typedef MyStruct;
-
-// int => int map
-#define i_key int
-#define i_val int
-#include <stc/cmap.h>
-
-// Point => int map
-struct Point { int x, y; } typedef Point;
-
-int point_cmp(const Point* a, const Point* b) {
- int c = a->x - b->x;
- return c ? c : a->y - b->y;
-}
-
-// Point => int map
-#define i_key Point
-#define i_val int
-#define i_cmp point_cmp
-#define i_hash c_default_hash
-#define i_opt c_is_fwd
-#define i_tag pnt
-#include <stc/cmap.h>
-
-// cstr => cstr map
-#define i_key_str
-#define i_val_str
-#include <stc/cmap.h>
-
-// string set
-#define i_key_str
-#include <stc/cset.h>
-
-
-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);
-
- c_apply(v, cmap_pnt_insert(&pmap, c_pair(v)), cmap_pnt_raw, {
- {{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("");
-
- c_apply(v, cmap_str_emplace(&smap, c_pair(v)), cmap_str_raw, {
- {"Hello, friend", "long time no see"},
- {"So long, friend", "see you around"},
- });
-
- c_apply(v, cset_str_emplace(&sset, *v), const char*, {
- "Hello, friend",
- "Nice to see you again",
- "So long, friend",
- });
- c_foreach (i, cset_str, sset)
- printf(" %s\n", cstr_str(i.ref));
- }
-}
+#define i_implement +#include <stc/cstr.h> +#include <stc/forward.h> + +forward_cmap(cmap_pnt, struct Point, int); + +struct MyStruct { + cmap_pnt pntmap; + cstr name; +} typedef MyStruct; + +// int => int map +#define i_key int +#define i_val int +#include <stc/cmap.h> + +// Point => int map +struct Point { int x, y; } typedef Point; + +int point_cmp(const Point* a, const Point* b) { + int c = a->x - b->x; + return c ? c : a->y - b->y; +} + +// Point => int map +#define i_key Point +#define i_val int +#define i_cmp point_cmp +#define i_hash c_default_hash +#define i_opt c_is_fwd +#define i_tag pnt +#include <stc/cmap.h> + +// cstr => cstr map +#define i_key_str +#define i_val_str +#include <stc/cmap.h> + +// string set +#define i_key_str +#include <stc/cset.h> + + +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); + + c_apply(v, cmap_pnt_insert(&pmap, c_pair(v)), cmap_pnt_raw, { + {{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(""); + + c_apply(v, cmap_str_emplace(&smap, c_pair(v)), cmap_str_raw, { + {"Hello, friend", "long time no see"}, + {"So long, friend", "see you around"}, + }); + + c_apply(v, cset_str_emplace(&sset, *v), const char*, { + "Hello, friend", + "Nice to see you again", + "So long, friend", + }); + c_foreach (i, cset_str, sset) + printf(" %s\n", cstr_str(i.ref)); + } +} diff --git a/examples/new_pque.c b/examples/new_pque.c index 79e895d8..2e5cf9ca 100644 --- a/examples/new_pque.c +++ b/examples/new_pque.c @@ -1,65 +1,65 @@ -#include <stc/forward.h>
-
-forward_cpque(cpque_pnt, struct Point);
-
-struct MyStruct {
- cpque_pnt priority_queue;
- int id;
-};
-
-#define i_val int
-#include <stc/cstack.h>
-
-#define i_val int
-#include <stc/cpque.h>
-
-struct Point { int x, y; } typedef Point;
-
-int Point_cmp(const Point* a, const Point* b) {
- int c = a->x - b->x;
- return c ? c : a->y - b->y;
-}
-
-#define i_val Point
-#define i_cmp Point_cmp
-#define i_opt c_is_fwd
-#define i_tag pnt
-#include <stc/cpque.h>
-
-#include <stdio.h>
-
-int main()
-{
- c_auto (cstack_int, istk)
- {
- cstack_int_push(&istk, 123);
- cstack_int_push(&istk, 321);
- // print
- c_foreach (i, cstack_int, istk)
- printf(" %d", *i.ref);
- puts("");
- }
- c_auto (cpque_pnt, pque)
- {
- cpque_pnt_push(&pque, (Point){23, 80});
- cpque_pnt_push(&pque, (Point){12, 32});
- cpque_pnt_push(&pque, (Point){54, 74});
- cpque_pnt_push(&pque, (Point){12, 62});
- // print
- while (!cpque_pnt_empty(pque)) {
- cpque_pnt_value *v = cpque_pnt_top(&pque);
- printf(" (%d,%d)", v->x, v->y);
- cpque_pnt_pop(&pque);
- }
- puts("");
- }
- c_auto (cpque_int, ique)
- {
- cpque_int_push(&ique, 123);
- cpque_int_push(&ique, 321);
- // print
- for (size_t i=0; i<cpque_int_size(ique); ++i)
- printf(" %d", ique.data[i]);
- puts("");
- }
-}
+#include <stc/forward.h> + +forward_cpque(cpque_pnt, struct Point); + +struct MyStruct { + cpque_pnt priority_queue; + int id; +}; + +#define i_val int +#include <stc/cstack.h> + +#define i_val int +#include <stc/cpque.h> + +struct Point { int x, y; } typedef Point; + +int Point_cmp(const Point* a, const Point* b) { + int c = a->x - b->x; + return c ? c : a->y - b->y; +} + +#define i_val Point +#define i_cmp Point_cmp +#define i_opt c_is_fwd +#define i_tag pnt +#include <stc/cpque.h> + +#include <stdio.h> + +int main() +{ + c_auto (cstack_int, istk) + { + cstack_int_push(&istk, 123); + cstack_int_push(&istk, 321); + // print + c_foreach (i, cstack_int, istk) + printf(" %d", *i.ref); + puts(""); + } + c_auto (cpque_pnt, pque) + { + cpque_pnt_push(&pque, (Point){23, 80}); + cpque_pnt_push(&pque, (Point){12, 32}); + cpque_pnt_push(&pque, (Point){54, 74}); + cpque_pnt_push(&pque, (Point){12, 62}); + // print + while (!cpque_pnt_empty(pque)) { + cpque_pnt_value *v = cpque_pnt_top(&pque); + printf(" (%d,%d)", v->x, v->y); + cpque_pnt_pop(&pque); + } + puts(""); + } + c_auto (cpque_int, ique) + { + cpque_int_push(&ique, 123); + cpque_int_push(&ique, 321); + // print + for (size_t i=0; i<cpque_int_size(ique); ++i) + printf(" %d", ique.data[i]); + puts(""); + } +} diff --git a/examples/new_queue.c b/examples/new_queue.c index 86f4227c..f0d8120f 100644 --- a/examples/new_queue.c +++ b/examples/new_queue.c @@ -1,45 +1,45 @@ -#define i_implement
-#include <stc/crandom.h>
-#include <stc/forward.h>
-#include <stdio.h>
-#include <time.h>
-
-forward_cqueue(cqueue_pnt, struct Point);
-
-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);
-}
-#define i_val Point
-#define i_cmp point_cmp
-#define i_opt c_is_fwd
-#define i_tag pnt
-#include <stc/cqueue.h>
-
-#define i_val int
-#include <stc/cqueue.h>
-
-int main() {
- int n = 60000000;
- stc64_t rng = stc64_new(time(NULL));
- stc64_uniform_t dist = stc64_uniform_new(0, n);
-
- c_auto (cqueue_int, Q)
- {
- // Push eight million random numbers onto the queue.
- for (int i=0; i<n; ++i)
- cqueue_int_push(&Q, stc64_uniform(&rng, &dist));
-
- // Push or pop on the queue ten million times
- printf("befor: size %" PRIuMAX ", capacity %" PRIuMAX "\n", cqueue_int_size(Q), cqueue_int_capacity(Q));
- for (int i=n; i>0; --i) {
- int r = stc64_uniform(&rng, &dist);
- if (r & 1)
- cqueue_int_push(&Q, r);
- else
- cqueue_int_pop(&Q);
- }
- printf("after: size %" PRIuMAX ", capacity %" PRIuMAX "\n", cqueue_int_size(Q), cqueue_int_capacity(Q));
- }
-}
+#define i_implement +#include <stc/crandom.h> +#include <stc/forward.h> +#include <stdio.h> +#include <time.h> + +forward_cqueue(cqueue_pnt, struct Point); + +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); +} +#define i_val Point +#define i_cmp point_cmp +#define i_opt c_is_fwd +#define i_tag pnt +#include <stc/cqueue.h> + +#define i_val int +#include <stc/cqueue.h> + +int main() { + int n = 60000000; + stc64_t rng = stc64_new(time(NULL)); + stc64_uniform_t dist = stc64_uniform_new(0, n); + + c_auto (cqueue_int, Q) + { + // Push eight million random numbers onto the queue. + for (int i=0; i<n; ++i) + cqueue_int_push(&Q, stc64_uniform(&rng, &dist)); + + // Push or pop on the queue ten million times + printf("befor: size %" PRIuMAX ", capacity %" PRIuMAX "\n", cqueue_int_size(Q), cqueue_int_capacity(Q)); + for (int i=n; i>0; --i) { + int r = stc64_uniform(&rng, &dist); + if (r & 1) + cqueue_int_push(&Q, r); + else + cqueue_int_pop(&Q); + } + printf("after: size %" PRIuMAX ", capacity %" PRIuMAX "\n", cqueue_int_size(Q), cqueue_int_capacity(Q)); + } +} diff --git a/examples/new_smap.c b/examples/new_smap.c index 2a885d03..141934d3 100644 --- a/examples/new_smap.c +++ b/examples/new_smap.c @@ -1,76 +1,76 @@ -#define i_implement
-#include <stc/cstr.h>
-#include <stc/forward.h>
-
-forward_csmap(PMap, struct Point, int);
-
-// Use forward declared PMap in struct
-struct MyStruct {
- PMap pntmap;
- cstr name;
-} typedef MyStruct;
-
-// int => int map
-#define i_key int
-#define i_val int
-#include <stc/csmap.h>
-
-// Point => int map
-struct Point { int x, y; } typedef Point;
-int point_cmp(const Point* a, const Point* b) {
- int c = a->x - b->x;
- return c ? c : a->y - b->y;
-}
-
-#define i_type PMap
-#define i_key Point
-#define i_val int
-#define i_cmp point_cmp
-#define i_opt c_is_fwd
-#include <stc/csmap.h>
-
-// cstr => cstr map
-#define i_type SMap
-#define i_key_str
-#define i_val_str
-#include <stc/csmap.h>
-
-// cstr set
-#define i_type SSet
-#define i_key_str
-#include <stc/csset.h>
-
-
-int main()
-{
- c_auto (csmap_int, imap) {
- csmap_int_insert(&imap, 123, 321);
- }
-
- c_auto (PMap, pmap) {
- c_apply(v, PMap_insert(&pmap, c_pair(v)), PMap_value, {
- {{42, 14}, 1},
- {{32, 94}, 2},
- {{62, 81}, 3},
- });
- c_forpair (p, i, PMap, pmap)
- printf(" (%d,%d: %d)", _.p->x, _.p->y, *_.i);
- puts("");
- }
-
- c_auto (SMap, smap) {
- c_apply(v, SMap_emplace(&smap, c_pair(v)), SMap_raw, {
- {"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_auto (SSet, sset) {
- SSet_emplace(&sset, "Hello, friend");
- SSet_emplace(&sset, "Goodbye, foe");
- printf("Found? %s\n", SSet_contains(&sset, "Hello, friend") ? "true" : "false");
- }
-}
+#define i_implement +#include <stc/cstr.h> +#include <stc/forward.h> + +forward_csmap(PMap, struct Point, int); + +// Use forward declared PMap in struct +struct MyStruct { + PMap pntmap; + cstr name; +} typedef MyStruct; + +// int => int map +#define i_key int +#define i_val int +#include <stc/csmap.h> + +// Point => int map +struct Point { int x, y; } typedef Point; +int point_cmp(const Point* a, const Point* b) { + int c = a->x - b->x; + return c ? c : a->y - b->y; +} + +#define i_type PMap +#define i_key Point +#define i_val int +#define i_cmp point_cmp +#define i_opt c_is_fwd +#include <stc/csmap.h> + +// cstr => cstr map +#define i_type SMap +#define i_key_str +#define i_val_str +#include <stc/csmap.h> + +// cstr set +#define i_type SSet +#define i_key_str +#include <stc/csset.h> + + +int main() +{ + c_auto (csmap_int, imap) { + csmap_int_insert(&imap, 123, 321); + } + + c_auto (PMap, pmap) { + c_apply(v, PMap_insert(&pmap, c_pair(v)), PMap_value, { + {{42, 14}, 1}, + {{32, 94}, 2}, + {{62, 81}, 3}, + }); + c_forpair (p, i, PMap, pmap) + printf(" (%d,%d: %d)", _.p->x, _.p->y, *_.i); + puts(""); + } + + c_auto (SMap, smap) { + c_apply(v, SMap_emplace(&smap, c_pair(v)), SMap_raw, { + {"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_auto (SSet, sset) { + SSet_emplace(&sset, "Hello, friend"); + SSet_emplace(&sset, "Goodbye, foe"); + printf("Found? %s\n", SSet_contains(&sset, "Hello, friend") ? "true" : "false"); + } +} diff --git a/examples/new_sptr.c b/examples/new_sptr.c index 58f68dae..e2d4da85 100644 --- a/examples/new_sptr.c +++ b/examples/new_sptr.c @@ -1,56 +1,56 @@ -#define i_implement
-#include <stc/cstr.h>
-
-struct Person { cstr name, last; } typedef Person;
-
-Person Person_new(const char* name, const char* last) {
- return (Person){.name = cstr_from(name), .last = cstr_from(last)};
-}
-Person Person_clone(Person p) {
- p.name = cstr_clone(p.name), p.last = cstr_clone(p.last);
- return p;
-}
-void Person_drop(Person* p) {
- printf("drop: %s %s\n", cstr_str(&p->name), cstr_str(&p->last));
- c_drop(cstr, &p->name, &p->last);
-}
-
-#define i_val_bind Person
-#define i_opt c_no_cmp // makes cmp and hash not required when using _bind
-#define i_tag person
-#include <stc/carc.h>
-
-// ...
-#define i_type SPtr
-#define i_val int
-#define i_valdrop(x) printf("drop: %d\n", *x)
-#include <stc/carc.h>
-
-#define i_val_arcbox SPtr
-#define i_tag iptr
-#include <stc/cstack.h>
-
-int main(void) {
- c_auto (carc_person, p, q, r, s)
- {
- puts("Ex1");
- p = carc_person_make(Person_new("John", "Smiths"));
- q = carc_person_clone(p);
- r = carc_person_clone(p);
- s = carc_person_make(Person_clone(*p.get)); // deep copy
- printf("%s %s. uses: %lu\n", cstr_str(&r.get->name), cstr_str(&s.get->last), *p.use_count);
- }
-
- c_auto (cstack_iptr, stk) {
- puts("Ex2");
- cstack_iptr_push(&stk, SPtr_make(10));
- cstack_iptr_push(&stk, SPtr_make(20));
- cstack_iptr_push(&stk, SPtr_make(30));
- cstack_iptr_push(&stk, SPtr_clone(*cstack_iptr_top(&stk)));
- cstack_iptr_push(&stk, SPtr_clone(*cstack_iptr_begin(&stk).ref));
-
- c_foreach (i, cstack_iptr, stk)
- printf(" (%d, uses %ld)", *i.ref->get, *i.ref->use_count);
- puts("");
- }
-}
+#define i_implement +#include <stc/cstr.h> + +struct Person { cstr name, last; } typedef Person; + +Person Person_new(const char* name, const char* last) { + return (Person){.name = cstr_from(name), .last = cstr_from(last)}; +} +Person Person_clone(Person p) { + p.name = cstr_clone(p.name), p.last = cstr_clone(p.last); + return p; +} +void Person_drop(Person* p) { + printf("drop: %s %s\n", cstr_str(&p->name), cstr_str(&p->last)); + c_drop(cstr, &p->name, &p->last); +} + +#define i_val_bind Person +#define i_opt c_no_cmp // makes cmp and hash not required when using _bind +#define i_tag person +#include <stc/carc.h> + +// ... +#define i_type SPtr +#define i_val int +#define i_valdrop(x) printf("drop: %d\n", *x) +#include <stc/carc.h> + +#define i_val_arcbox SPtr +#define i_tag iptr +#include <stc/cstack.h> + +int main(void) { + c_auto (carc_person, p, q, r, s) + { + puts("Ex1"); + p = carc_person_make(Person_new("John", "Smiths")); + q = carc_person_clone(p); + r = carc_person_clone(p); + s = carc_person_make(Person_clone(*p.get)); // deep copy + printf("%s %s. uses: %lu\n", cstr_str(&r.get->name), cstr_str(&s.get->last), *p.use_count); + } + + c_auto (cstack_iptr, stk) { + puts("Ex2"); + cstack_iptr_push(&stk, SPtr_make(10)); + cstack_iptr_push(&stk, SPtr_make(20)); + cstack_iptr_push(&stk, SPtr_make(30)); + cstack_iptr_push(&stk, SPtr_clone(*cstack_iptr_top(&stk))); + cstack_iptr_push(&stk, SPtr_clone(*cstack_iptr_begin(&stk).ref)); + + c_foreach (i, cstack_iptr, stk) + printf(" (%d, uses %ld)", *i.ref->get, *i.ref->use_count); + puts(""); + } +} diff --git a/examples/new_vec.c b/examples/new_vec.c index 3f3d5de8..73e4987f 100644 --- a/examples/new_vec.c +++ b/examples/new_vec.c @@ -1,57 +1,57 @@ -#define i_implement
-#include <stc/cstr.h>
-#include <stc/forward.h>
-
-forward_cvec(cvec_i32, int);
-forward_cvec(cvec_pnt, struct Point);
-
-struct MyStruct {
- cvec_i32 intvec;
- cvec_pnt pntvec;
-} typedef MyStruct;
-
-#define i_val int
-#define i_opt c_is_fwd
-#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);
-}
-
-#define i_val Point
-#define i_cmp point_cmp
-#define i_opt c_is_fwd
-#define i_tag pnt
-#include <stc/cvec.h>
-
-#define i_val float
-#include <stc/cvec.h>
-
-#define i_val_str
-#include <stc/cvec.h>
-
-
-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_back(&vec, 123);
- cvec_float_push_back(&fvec, 123.3);
-
- cvec_pnt_push_back(&pvec, (Point){42, 14});
- cvec_pnt_push_back(&pvec, (Point){32, 94});
- cvec_pnt_push_back(&pvec, (Point){62, 81});
- cvec_pnt_sort(&pvec);
- c_foreach (i, cvec_pnt, pvec)
- printf(" (%d %d)", i.ref->x, i.ref->y);
- puts("");
-
- cvec_str_emplace_back(&svec, "Hello, friend");
- }
-}
+#define i_implement +#include <stc/cstr.h> +#include <stc/forward.h> + +forward_cvec(cvec_i32, int); +forward_cvec(cvec_pnt, struct Point); + +struct MyStruct { + cvec_i32 intvec; + cvec_pnt pntvec; +} typedef MyStruct; + +#define i_val int +#define i_opt c_is_fwd +#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); +} + +#define i_val Point +#define i_cmp point_cmp +#define i_opt c_is_fwd +#define i_tag pnt +#include <stc/cvec.h> + +#define i_val float +#include <stc/cvec.h> + +#define i_val_str +#include <stc/cvec.h> + + +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_back(&vec, 123); + cvec_float_push_back(&fvec, 123.3); + + cvec_pnt_push_back(&pvec, (Point){42, 14}); + cvec_pnt_push_back(&pvec, (Point){32, 94}); + cvec_pnt_push_back(&pvec, (Point){62, 81}); + cvec_pnt_sort(&pvec); + c_foreach (i, cvec_pnt, pvec) + printf(" (%d %d)", i.ref->x, i.ref->y); + puts(""); + + cvec_str_emplace_back(&svec, "Hello, friend"); + } +} diff --git a/examples/person_arc.c b/examples/person_arc.c index 5ac1e9c2..685d1b3c 100644 --- a/examples/person_arc.c +++ b/examples/person_arc.c @@ -1,72 +1,72 @@ -/* cbox: heap allocated boxed type */
-#define i_implement
-#include <stc/cstr.h>
-
-typedef struct { cstr name, last; } Person;
-
-Person Person_new(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) {
- int c = cstr_cmp(&a->name, &b->name);
- return c ? c : cstr_cmp(&a->last, &b->last);
-}
-
-uint64_t Person_hash(const Person* a) {
- return cstr_hash(&a->name) ^ cstr_hash(&a->last);
-}
-
-Person Person_clone(Person p) {
- p.name = cstr_clone(p.name);
- p.last = cstr_clone(p.last);
- return p;
-}
-
-void Person_drop(Person* p) {
- printf("drop: %s %s\n", cstr_str(&p->name), cstr_str(&p->last));
- c_drop(cstr, &p->name, &p->last);
-}
-
-#define i_type PSPtr
-#define i_val_bind Person // binds Person_cmp, ...
-#include <stc/carc.h>
-
-#define i_type Persons
-#define i_val_arcbox PSPtr // binds PSPtr_cmp, ...
-#include <stc/cvec.h>
-
-
-int main()
-{
- c_auto (Persons, vec)
- c_auto (PSPtr, p, q)
- {
- p = PSPtr_make(Person_new("Laura", "Palmer"));
-
- // We want a deep copy -- PSPtr_clone(p) only shares!
- q = PSPtr_make(Person_clone(*p.get));
- cstr_assign(&q.get->name, "Leland");
-
- printf("orig: %s %s\n", cstr_str(&p.get->name), cstr_str(&p.get->last));
- printf("copy: %s %s\n", cstr_str(&q.get->name), cstr_str(&q.get->last));
-
- Persons_push_back(&vec, PSPtr_make(Person_new("Dale", "Cooper")));
- Persons_push_back(&vec, PSPtr_make(Person_new("Audrey", "Home")));
-
- // Clone/share p and q to the vector
- c_apply(v, Persons_push_back(&vec, PSPtr_clone(*v)), PSPtr, {p, q});
-
- c_foreach (i, Persons, vec)
- printf("%s %s\n", cstr_str(&i.ref->get->name), cstr_str(&i.ref->get->last));
- puts("");
-
- // Look-up Audrey!
- c_autovar (Person a = Person_new("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("");
- }
-}
+/* cbox: heap allocated boxed type */ +#define i_implement +#include <stc/cstr.h> + +typedef struct { cstr name, last; } Person; + +Person Person_new(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) { + int c = cstr_cmp(&a->name, &b->name); + return c ? c : cstr_cmp(&a->last, &b->last); +} + +uint64_t Person_hash(const Person* a) { + return cstr_hash(&a->name) ^ cstr_hash(&a->last); +} + +Person Person_clone(Person p) { + p.name = cstr_clone(p.name); + p.last = cstr_clone(p.last); + return p; +} + +void Person_drop(Person* p) { + printf("drop: %s %s\n", cstr_str(&p->name), cstr_str(&p->last)); + c_drop(cstr, &p->name, &p->last); +} + +#define i_type PSPtr +#define i_val_bind Person // binds Person_cmp, ... +#include <stc/carc.h> + +#define i_type Persons +#define i_val_arcbox PSPtr // binds PSPtr_cmp, ... +#include <stc/cvec.h> + + +int main() +{ + c_auto (Persons, vec) + c_auto (PSPtr, p, q) + { + p = PSPtr_make(Person_new("Laura", "Palmer")); + + // We want a deep copy -- PSPtr_clone(p) only shares! + q = PSPtr_make(Person_clone(*p.get)); + cstr_assign(&q.get->name, "Leland"); + + printf("orig: %s %s\n", cstr_str(&p.get->name), cstr_str(&p.get->last)); + printf("copy: %s %s\n", cstr_str(&q.get->name), cstr_str(&q.get->last)); + + Persons_push_back(&vec, PSPtr_make(Person_new("Dale", "Cooper"))); + Persons_push_back(&vec, PSPtr_make(Person_new("Audrey", "Home"))); + + // Clone/share p and q to the vector + c_apply(v, Persons_push_back(&vec, PSPtr_clone(*v)), PSPtr, {p, q}); + + c_foreach (i, Persons, vec) + printf("%s %s\n", cstr_str(&i.ref->get->name), cstr_str(&i.ref->get->last)); + puts(""); + + // Look-up Audrey! + c_autovar (Person a = Person_new("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(""); + } +} diff --git a/examples/phonebook.c b/examples/phonebook.c index ab782653..2368480c 100644 --- a/examples/phonebook.c +++ b/examples/phonebook.c @@ -1,81 +1,81 @@ -// The MIT License (MIT)
-// Copyright (c) 2018 Maksim Andrianov
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to
-// deal in the Software without restriction, including without limitation the
-// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-// sell copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-// IN THE SOFTWARE.
-
-// Program to emulates the phone book.
-
-#define i_implement
-#include <stc/cstr.h>
-
-#define i_key_str
-#define i_val_str
-#include <stc/cmap.h>
-
-#define i_key_str
-#include <stc/cset.h>
-
-void print_phone_book(cmap_str phone_book)
-{
- c_foreach (i, cmap_str, phone_book)
- printf("%s\t- %s\n", cstr_str(&i.ref->first), cstr_str(&i.ref->second));
-}
-
-int main(int argc, char **argv)
-{
- c_auto (cset_str, names) {
- c_apply(v, cset_str_emplace(&names, *v), const char*,
- {"Hello", "Cool", "True"});
- c_foreach (i, cset_str, names) printf("%s ", cstr_str(i.ref));
- puts("");
- }
-
- c_auto (cmap_str, phone_book) {
- c_apply(v, cmap_str_emplace(&phone_book, c_pair(v)), cmap_str_raw, {
- {"Lilia Friedman", "(892) 670-4739"},
- {"Tariq Beltran", "(489) 600-7575"},
- {"Laiba Juarez", "(303) 885-5692"},
- {"Elliott Mooney", "(945) 616-4482"},
- });
-
- printf("Phone book:\n");
- print_phone_book(phone_book);
-
- cmap_str_emplace(&phone_book, "Zak Byers", "(551) 396-1880");
- cmap_str_emplace(&phone_book, "Zak Byers", "(551) 396-1990");
-
- printf("\nPhone book after adding Zak Byers:\n");
- print_phone_book(phone_book);
-
- if (cmap_str_contains(&phone_book, "Tariq Beltran"))
- printf("\nTariq Beltran is in phone book\n");
-
- cmap_str_erase(&phone_book, "Tariq Beltran");
- cmap_str_erase(&phone_book, "Elliott Mooney");
-
- printf("\nPhone book after erasing Tariq and Elliott:\n");
- print_phone_book(phone_book);
-
- cmap_str_emplace_or_assign(&phone_book, "Zak Byers", "(555) 396-188");
-
- printf("\nPhone book after update phone of Zak Byers:\n");
- print_phone_book(phone_book);
- }
- puts("done");
-}
+// The MIT License (MIT) +// Copyright (c) 2018 Maksim Andrianov +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +// Program to emulates the phone book. + +#define i_implement +#include <stc/cstr.h> + +#define i_key_str +#define i_val_str +#include <stc/cmap.h> + +#define i_key_str +#include <stc/cset.h> + +void print_phone_book(cmap_str phone_book) +{ + c_foreach (i, cmap_str, phone_book) + printf("%s\t- %s\n", cstr_str(&i.ref->first), cstr_str(&i.ref->second)); +} + +int main(int argc, char **argv) +{ + c_auto (cset_str, names) { + c_apply(v, cset_str_emplace(&names, *v), const char*, + {"Hello", "Cool", "True"}); + c_foreach (i, cset_str, names) printf("%s ", cstr_str(i.ref)); + puts(""); + } + + c_auto (cmap_str, phone_book) { + c_apply(v, cmap_str_emplace(&phone_book, c_pair(v)), cmap_str_raw, { + {"Lilia Friedman", "(892) 670-4739"}, + {"Tariq Beltran", "(489) 600-7575"}, + {"Laiba Juarez", "(303) 885-5692"}, + {"Elliott Mooney", "(945) 616-4482"}, + }); + + printf("Phone book:\n"); + print_phone_book(phone_book); + + cmap_str_emplace(&phone_book, "Zak Byers", "(551) 396-1880"); + cmap_str_emplace(&phone_book, "Zak Byers", "(551) 396-1990"); + + printf("\nPhone book after adding Zak Byers:\n"); + print_phone_book(phone_book); + + if (cmap_str_contains(&phone_book, "Tariq Beltran")) + printf("\nTariq Beltran is in phone book\n"); + + cmap_str_erase(&phone_book, "Tariq Beltran"); + cmap_str_erase(&phone_book, "Elliott Mooney"); + + printf("\nPhone book after erasing Tariq and Elliott:\n"); + print_phone_book(phone_book); + + cmap_str_emplace_or_assign(&phone_book, "Zak Byers", "(555) 396-188"); + + printf("\nPhone book after update phone of Zak Byers:\n"); + print_phone_book(phone_book); + } + puts("done"); +} diff --git a/examples/prime.c b/examples/prime.c index 92fafde4..f235f845 100644 --- a/examples/prime.c +++ b/examples/prime.c @@ -1,42 +1,42 @@ -#include <stdio.h>
-#include <math.h>
-#include <time.h>
-#define i_implement
-#include <stc/cbits.h>
-
-cbits sieveOfEratosthenes(size_t n)
-{
- cbits bits = cbits_with_size(n/2 + 1, true);
- size_t q = (size_t) sqrt((double) n) + 1;
- for (size_t i = 3; i < q; i += 2) {
- size_t j = i;
- for (; j < n; j += 2) {
- if (cbits_test(&bits, j>>1)) {
- i = j;
- break;
- }
- }
- for (size_t j = i*i; j < n; j += i*2)
- cbits_reset(&bits, j>>1);
- }
- return bits;
-}
-
-int main(void)
-{
- size_t n = 1000000000;
- printf("computing prime numbers up to %" PRIuMAX "\n", n);
-
- clock_t t1 = clock();
- c_autovar (cbits primes = sieveOfEratosthenes(n + 1), cbits_drop(&primes)) {
- puts("done");
- size_t np = cbits_count(&primes);
- clock_t t2 = clock();
-
- printf("number of primes: %" PRIuMAX ", time: %f\n", np, (t2 - t1) / (float)CLOCKS_PER_SEC);
- printf("2");
- for (size_t i = 3; i < 1000; i += 2)
- if (cbits_test(&primes, i>>1)) printf(" %" PRIuMAX "", i);
- puts("");
- }
-}
+#include <stdio.h> +#include <math.h> +#include <time.h> +#define i_implement +#include <stc/cbits.h> + +cbits sieveOfEratosthenes(size_t n) +{ + cbits bits = cbits_with_size(n/2 + 1, true); + size_t q = (size_t) sqrt((double) n) + 1; + for (size_t i = 3; i < q; i += 2) { + size_t j = i; + for (; j < n; j += 2) { + if (cbits_test(&bits, j>>1)) { + i = j; + break; + } + } + for (size_t j = i*i; j < n; j += i*2) + cbits_reset(&bits, j>>1); + } + return bits; +} + +int main(void) +{ + size_t n = 1000000000; + printf("computing prime numbers up to %" PRIuMAX "\n", n); + + clock_t t1 = clock(); + c_autovar (cbits primes = sieveOfEratosthenes(n + 1), cbits_drop(&primes)) { + puts("done"); + size_t np = cbits_count(&primes); + clock_t t2 = clock(); + + printf("number of primes: %" PRIuMAX ", time: %f\n", np, (t2 - t1) / (float)CLOCKS_PER_SEC); + printf("2"); + for (size_t i = 3; i < 1000; i += 2) + if (cbits_test(&primes, i>>1)) printf(" %" PRIuMAX "", i); + puts(""); + } +} diff --git a/examples/priority.c b/examples/priority.c index 65543590..f4c45d76 100644 --- a/examples/priority.c +++ b/examples/priority.c @@ -1,35 +1,35 @@ -
-#include <stdio.h>
-#include <time.h>
-#define i_implement
-#include <stc/crandom.h>
-
-#define i_val int64_t
-#define i_cmp -c_default_cmp // min-heap (increasing values)
-#define i_tag i
-#include <stc/cpque.h>
-
-int main() {
- size_t N = 10000000;
- stc64_t rng = stc64_new(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 %" PRIuMAX " numbers\n", N);
- c_forrange (N)
- cpque_i_push(&heap, stc64_uniform(&rng, &dist));
-
- // push some negative numbers too.
- c_apply(v, cpque_i_push(&heap, *v), int, {-231, -32, -873, -4, -343});
-
- c_forrange (N)
- cpque_i_push(&heap, stc64_uniform(&rng, &dist));
-
- puts("Extract the hundred smallest.");
- c_forrange (100) {
- printf("%" PRIdMAX " ", *cpque_i_top(&heap));
- cpque_i_pop(&heap);
- }
- }
-}
+ +#include <stdio.h> +#include <time.h> +#define i_implement +#include <stc/crandom.h> + +#define i_val int64_t +#define i_cmp -c_default_cmp // min-heap (increasing values) +#define i_tag i +#include <stc/cpque.h> + +int main() { + size_t N = 10000000; + stc64_t rng = stc64_new(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 %" PRIuMAX " numbers\n", N); + c_forrange (N) + cpque_i_push(&heap, stc64_uniform(&rng, &dist)); + + // push some negative numbers too. + c_apply(v, cpque_i_push(&heap, *v), int, {-231, -32, -873, -4, -343}); + + c_forrange (N) + cpque_i_push(&heap, stc64_uniform(&rng, &dist)); + + puts("Extract the hundred smallest."); + c_forrange (100) { + printf("%" PRIdMAX " ", *cpque_i_top(&heap)); + cpque_i_pop(&heap); + } + } +} diff --git a/examples/queue.c b/examples/queue.c index 1b56d96a..57e24fe6 100644 --- a/examples/queue.c +++ b/examples/queue.c @@ -1,32 +1,32 @@ -#define i_implement
-#include <stc/crandom.h>
-#include <stdio.h>
-
-#define i_val int
-#define i_tag i
-#include <stc/cqueue.h>
-
-int main() {
- int n = 100000000;
- stc64_uniform_t dist;
- 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, 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 = stc64_uniform(&rng, &dist);
- if (r & 1)
- ++n, cqueue_i_push(&queue, r);
- else
- --n, cqueue_i_pop(&queue);
- }
- printf("%d, %" PRIuMAX "\n", n, cqueue_i_size(queue));
- }
-}
+#define i_implement +#include <stc/crandom.h> +#include <stdio.h> + +#define i_val int +#define i_tag i +#include <stc/cqueue.h> + +int main() { + int n = 100000000; + stc64_uniform_t dist; + 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, 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 = stc64_uniform(&rng, &dist); + if (r & 1) + ++n, cqueue_i_push(&queue, r); + else + --n, cqueue_i_pop(&queue); + } + printf("%d, %" PRIuMAX "\n", n, cqueue_i_size(queue)); + } +} diff --git a/examples/random.c b/examples/random.c index 39fd7fa1..fc7745e5 100644 --- a/examples/random.c +++ b/examples/random.c @@ -1,43 +1,43 @@ -#include <stdio.h>
-#include <time.h>
-#define i_implement
-#include <stc/crandom.h>
-
-int main()
-{
- const size_t N = 1000000000;
- const uint64_t seed = time(NULL), range = 1000000;
- stc64_t rng = stc64_new(seed);
-
- uint64_t sum;
- clock_t diff, before;
-
- printf("Compare speed of full and unbiased ranged random numbers...\n");
- sum = 0;
- before = clock();
- c_forrange (N) {
- sum += (uint32_t) stc64_rand(&rng);
- }
- diff = clock() - before;
- printf("full range\t\t: %f secs, %" PRIuMAX ", avg: %f\n", (float) diff / CLOCKS_PER_SEC, N, (double) sum / N);
-
- stc64_uniform_t dist1 = stc64_uniform_new(0, range);
- rng = stc64_new(seed);
- sum = 0;
- before = clock();
- c_forrange (N) {
- sum += stc64_uniform(&rng, &dist1); // unbiased
- }
- diff = clock() - before;
- printf("unbiased 0-%" PRIuMAX "\t: %f secs, %" PRIuMAX ", avg: %f\n", range, (float) diff / CLOCKS_PER_SEC, N, (double) sum / N);
-
- sum = 0;
- rng = stc64_new(seed);
- before = clock();
- c_forrange (N) {
- sum += stc64_rand(&rng) % (range + 1); // biased
- }
- diff = clock() - before;
- printf("biased 0-%" PRIuMAX " \t: %f secs, %" PRIuMAX ", avg: %f\n", range, (float) diff / CLOCKS_PER_SEC, N, (double) sum / N);
-
-}
+#include <stdio.h> +#include <time.h> +#define i_implement +#include <stc/crandom.h> + +int main() +{ + const size_t N = 1000000000; + const uint64_t seed = time(NULL), range = 1000000; + stc64_t rng = stc64_new(seed); + + uint64_t sum; + clock_t diff, before; + + printf("Compare speed of full and unbiased ranged random numbers...\n"); + sum = 0; + before = clock(); + c_forrange (N) { + sum += (uint32_t) stc64_rand(&rng); + } + diff = clock() - before; + printf("full range\t\t: %f secs, %" PRIuMAX ", avg: %f\n", (float) diff / CLOCKS_PER_SEC, N, (double) sum / N); + + stc64_uniform_t dist1 = stc64_uniform_new(0, range); + rng = stc64_new(seed); + sum = 0; + before = clock(); + c_forrange (N) { + sum += stc64_uniform(&rng, &dist1); // unbiased + } + diff = clock() - before; + printf("unbiased 0-%" PRIuMAX "\t: %f secs, %" PRIuMAX ", avg: %f\n", range, (float) diff / CLOCKS_PER_SEC, N, (double) sum / N); + + sum = 0; + rng = stc64_new(seed); + before = clock(); + c_forrange (N) { + sum += stc64_rand(&rng) % (range + 1); // biased + } + diff = clock() - before; + printf("biased 0-%" PRIuMAX " \t: %f secs, %" PRIuMAX ", avg: %f\n", range, (float) diff / CLOCKS_PER_SEC, N, (double) sum / N); + +} diff --git a/examples/rawptr_elements.c b/examples/rawptr_elements.c index 64d73843..cfeb459d 100644 --- a/examples/rawptr_elements.c +++ b/examples/rawptr_elements.c @@ -1,68 +1,68 @@ -#include <stc/ccommon.h>
-#include <stdio.h>
-
-struct { double x, y; } typedef Point;
-
-// Set of Point pointers: define all template parameters "in-line"
-// Note it may be simpler to use a cbox for this.
-#define i_key Point*
-#define i_keydrop(x) c_free(*(x))
-#define i_keyclone(x) c_new(Point, *(x))
-#define i_hash(x) c_default_hash(*(x))
-#define i_cmp(x, y) memcmp(*(x), *(y), sizeof **(x)) // not good!
-#define i_tag pnt
-#include <stc/cset.h>
-
-#define i_implement
-#include <stc/cstr.h>
-// Map of int64 pointers: Define i_valraw as int64_t for easy emplace calls!
-typedef int64_t inttype;
-#define i_key_str
-#define i_val inttype*
-#define i_valraw inttype
-#define i_valfrom(raw) (puts("from"), c_new(inttype, raw))
-#define i_valto(x) (puts("to"), **(x))
-#define i_valclone c_derived_valclone // enables clone via valto+valfrom
-#define i_valdrop(x) c_free(*(x))
-#include <stc/cmap.h>
-
-int main()
-{
- c_auto (cset_pnt, set, cpy)
- {
- printf("Set with pointer elements:\n");
- // c++: set.insert(new Point{1.2, 3.4});
- cset_pnt_insert(&set, c_new(Point, {1.2, 3.4}));
- Point* q = *cset_pnt_insert(&set, c_new(Point, {6.1, 4.7})).ref;
- cset_pnt_insert(&set, c_new(Point, {5.7, 2.3}));
-
- cpy = cset_pnt_clone(set);
- cset_pnt_erase(&cpy, q);
-
- printf("set:");
- c_foreach (i, cset_pnt, set)
- printf(" (%g %g)", i.ref[0]->x, i.ref[0]->y);
-
- printf("\ncpy:");
- c_foreach (i, cset_pnt, cpy)
- printf(" (%g %g)", i.ref[0]->x, i.ref[0]->y);
- puts("");
- }
-
- c_auto (cmap_str, map, m2)
- {
- printf("\nMap with pointer elements:\n");
- cmap_str_insert(&map, cstr_new("testing"), c_new(inttype, 999));
- cmap_str_insert(&map, cstr_new("done"), c_new(inttype, 111));
-
- // Emplace: implicit key, val construction using i_keyfrom/i_valfrom:
- cmap_str_emplace(&map, "hello", 200);
- cmap_str_emplace(&map, "goodbye", 400);
-
- // default uses i_valfrom+i_valto when no i_valclone defined:
- m2 = cmap_str_clone(map);
-
- c_forpair (name, number, cmap_str, m2)
- printf("%s: %" PRIdMAX "\n", cstr_str(_.name), **_.number);
- }
-}
+#include <stc/ccommon.h> +#include <stdio.h> + +struct { double x, y; } typedef Point; + +// Set of Point pointers: define all template parameters "in-line" +// Note it may be simpler to use a cbox for this. +#define i_key Point* +#define i_keydrop(x) c_free(*(x)) +#define i_keyclone(x) c_new(Point, *(x)) +#define i_hash(x) c_default_hash(*(x)) +#define i_cmp(x, y) memcmp(*(x), *(y), sizeof **(x)) // not good! +#define i_tag pnt +#include <stc/cset.h> + +#define i_implement +#include <stc/cstr.h> +// Map of int64 pointers: Define i_valraw as int64_t for easy emplace calls! +typedef int64_t inttype; +#define i_key_str +#define i_val inttype* +#define i_valraw inttype +#define i_valfrom(raw) (puts("from"), c_new(inttype, raw)) +#define i_valto(x) (puts("to"), **(x)) +#define i_valclone c_derived_valclone // enables clone via valto+valfrom +#define i_valdrop(x) c_free(*(x)) +#include <stc/cmap.h> + +int main() +{ + c_auto (cset_pnt, set, cpy) + { + printf("Set with pointer elements:\n"); + // c++: set.insert(new Point{1.2, 3.4}); + cset_pnt_insert(&set, c_new(Point, {1.2, 3.4})); + Point* q = *cset_pnt_insert(&set, c_new(Point, {6.1, 4.7})).ref; + cset_pnt_insert(&set, c_new(Point, {5.7, 2.3})); + + cpy = cset_pnt_clone(set); + cset_pnt_erase(&cpy, q); + + printf("set:"); + c_foreach (i, cset_pnt, set) + printf(" (%g %g)", i.ref[0]->x, i.ref[0]->y); + + printf("\ncpy:"); + c_foreach (i, cset_pnt, cpy) + printf(" (%g %g)", i.ref[0]->x, i.ref[0]->y); + puts(""); + } + + c_auto (cmap_str, map, m2) + { + printf("\nMap with pointer elements:\n"); + cmap_str_insert(&map, cstr_new("testing"), c_new(inttype, 999)); + cmap_str_insert(&map, cstr_new("done"), c_new(inttype, 111)); + + // Emplace: implicit key, val construction using i_keyfrom/i_valfrom: + cmap_str_emplace(&map, "hello", 200); + cmap_str_emplace(&map, "goodbye", 400); + + // default uses i_valfrom+i_valto when no i_valclone defined: + m2 = cmap_str_clone(map); + + c_forpair (name, number, cmap_str, m2) + printf("%s: %" PRIdMAX "\n", cstr_str(_.name), **_.number); + } +} diff --git a/examples/read.c b/examples/read.c index 67b7e67e..74375a4f 100644 --- a/examples/read.c +++ b/examples/read.c @@ -1,26 +1,26 @@ -#define i_implement
-#include <stc/cstr.h>
-#define i_val_str
-#include <stc/cvec.h>
-#include <errno.h>
-
-cvec_str read_file(const char* name)
-{
- cvec_str vec = cvec_str_init();
- c_autovar (FILE* f = fopen(name, "r"), fclose(f))
- c_autovar (cstr line = cstr_init(), cstr_drop(&line))
- while (cstr_getline(&line, f))
- cvec_str_emplace_back(&vec, cstr_str(&line));
- return vec;
-}
-
-int main()
-{
- int n = 0;
- c_autovar (cvec_str vec = read_file(__FILE__), cvec_str_drop(&vec))
- c_foreach (i, cvec_str, vec)
- printf("%5d: %s\n", ++n, cstr_str(i.ref));
-
- if (errno)
- printf("error: read_file(" __FILE__ "). errno: %d\n", errno);
-}
+#define i_implement +#include <stc/cstr.h> +#define i_val_str +#include <stc/cvec.h> +#include <errno.h> + +cvec_str read_file(const char* name) +{ + cvec_str vec = cvec_str_init(); + c_autovar (FILE* f = fopen(name, "r"), fclose(f)) + c_autovar (cstr line = cstr_init(), cstr_drop(&line)) + while (cstr_getline(&line, f)) + cvec_str_emplace_back(&vec, cstr_str(&line)); + return vec; +} + +int main() +{ + int n = 0; + c_autovar (cvec_str vec = read_file(__FILE__), cvec_str_drop(&vec)) + c_foreach (i, cvec_str, vec) + printf("%5d: %s\n", ++n, cstr_str(i.ref)); + + if (errno) + printf("error: read_file(" __FILE__ "). errno: %d\n", errno); +} diff --git a/examples/replace.c b/examples/replace.c index 57018618..6084ede0 100644 --- a/examples/replace.c +++ b/examples/replace.c @@ -1,31 +1,31 @@ -#define i_implement
-#include <stc/cstr.h>
-
-int main ()
-{
- const char *base = "this is a test string.";
- const char *s2 = "n example";
- const char *s3 = "sample phrase";
-
- // replace signatures used in the same order as described above:
-
- // Ustring positions: 0123456789*123456789*12345
- cstr s = cstr_from(base); // "this is a test string."
- cstr m = cstr_clone(s);
- c_autodefer (cstr_drop(&s), cstr_drop(&m)) {
- cstr_append(&m, cstr_str(&m));
- cstr_append(&m, cstr_str(&m));
- printf("%s\n", cstr_str(&m));
-
- cstr_replace(&s, 9, 5, s2); // "this is an example string." (1)
- printf("(1) %s\n", cstr_str(&s));
- cstr_replace_n(&s, 19, 6, s3+7, 6); // "this is an example phrase." (2)
- printf("(2) %s\n", cstr_str(&s));
- cstr_replace(&s, 8, 10, "just a"); // "this is just a phrase." (3)
- printf("(3) %s\n", cstr_str(&s));
- cstr_replace_n(&s, 8, 6,"a shorty", 7); // "this is a short phrase." (4)
- printf("(4) %s\n", cstr_str(&s));
- cstr_replace(&s, 22, 1, "!!!"); // "this is a short phrase!!!" (5)
- printf("(5) %s\n", cstr_str(&s));
- }
-}
+#define i_implement +#include <stc/cstr.h> + +int main () +{ + const char *base = "this is a test string."; + const char *s2 = "n example"; + const char *s3 = "sample phrase"; + + // replace signatures used in the same order as described above: + + // Ustring positions: 0123456789*123456789*12345 + cstr s = cstr_from(base); // "this is a test string." + cstr m = cstr_clone(s); + c_autodefer (cstr_drop(&s), cstr_drop(&m)) { + cstr_append(&m, cstr_str(&m)); + cstr_append(&m, cstr_str(&m)); + printf("%s\n", cstr_str(&m)); + + cstr_replace(&s, 9, 5, s2); // "this is an example string." (1) + printf("(1) %s\n", cstr_str(&s)); + cstr_replace_n(&s, 19, 6, s3+7, 6); // "this is an example phrase." (2) + printf("(2) %s\n", cstr_str(&s)); + cstr_replace(&s, 8, 10, "just a"); // "this is just a phrase." (3) + printf("(3) %s\n", cstr_str(&s)); + cstr_replace_n(&s, 8, 6,"a shorty", 7); // "this is a short phrase." (4) + printf("(4) %s\n", cstr_str(&s)); + cstr_replace(&s, 22, 1, "!!!"); // "this is a short phrase!!!" (5) + printf("(5) %s\n", cstr_str(&s)); + } +} diff --git a/examples/shape.c b/examples/shape.c index d3534021..051e1c63 100644 --- a/examples/shape.c +++ b/examples/shape.c @@ -1,161 +1,161 @@ -// Demo of typesafe polymorphism in C99, using STC.
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <stc/ccommon.h>
-
-#define c_dyn_ptr(T, s) \
- (&T##_api == (s)->api ? (T*)(s) : (T*)0)
-
-#define c_vtable(Api, T) \
- c_static_assert(offsetof(T, base) == 0); \
- static Api T##_api
-
-// Shape definition
-// ============================================================
-
-typedef struct {
- float x, y;
-} Point;
-
-typedef struct Shape Shape;
-
-struct ShapeAPI {
- void (*drop)(Shape*);
- void (*draw)(const Shape*);
-};
-
-struct Shape {
- struct ShapeAPI* api;
- uint32_t color;
- uint16_t style;
- uint8_t thickness;
- uint8_t hardness;
-};
-
-void Shape_drop(Shape* shape)
-{
- printf("base destructed\n");
-}
-
-void Shape_delete(Shape* shape)
-{
- if (shape) {
- shape->api->drop(shape);
- c_free(shape);
- }
-}
-
-// Triangle implementation
-// ============================================================
-
-typedef struct {
- Shape base;
- Point p[3];
-} Triangle;
-
-c_vtable(struct ShapeAPI, Triangle);
-
-
-Triangle* Triangle_new(Point a, Point b, Point c)
-{
- return c_new(Triangle, {{.api=&Triangle_api}, .p={a, b, c}});
-}
-
-static void Triangle_draw(const Shape* shape)
-{
- const Triangle* self = c_dyn_ptr(Triangle, shape);
- printf("Triangle : (%g,%g), (%g,%g), (%g,%g)\n",
- self->p[0].x, self->p[0].y,
- self->p[1].x, self->p[1].y,
- self->p[2].x, self->p[2].y);
-}
-
-static struct ShapeAPI Triangle_api = {
- .drop = Shape_drop,
- .draw = Triangle_draw,
-};
-
-// Polygon implementation
-// ============================================================
-
-#define i_type PointVec
-#define i_val Point
-#include <stc/cstack.h>
-
-typedef struct {
- Shape base;
- PointVec points;
-} Polygon;
-
-c_vtable(struct ShapeAPI, Polygon);
-
-
-Polygon* Polygon_new(void)
-{
- return c_new(Polygon, {{.api=&Polygon_api}, .points=PointVec_init()});
-}
-
-void Polygon_addPoint(Polygon* self, Point p)
-{
- PointVec_push(&self->points, p);
-}
-
-static void Polygon_drop(Shape* shape)
-{
- Polygon* self = c_dyn_ptr(Polygon, shape);
- printf("poly destructed\n");
- PointVec_drop(&self->points);
- Shape_drop(shape);
-}
-
-static void Polygon_draw(const Shape* shape)
-{
- const Polygon* self = c_dyn_ptr(Polygon, shape);
- printf("Polygon :");
- c_foreach (i, PointVec, self->points)
- printf(" (%g,%g)", i.ref->x, i.ref->y);
- puts("");
-}
-
-static struct ShapeAPI Polygon_api = {
- .drop = Polygon_drop,
- .draw = Polygon_draw,
-};
-
-// Test
-// ============================================================
-
-#define i_type Shapes
-#define i_val Shape*
-#define i_valdrop(x) Shape_delete(*x)
-#include <stc/cstack.h>
-
-void testShape(const Shape* shape)
-{
- shape->api->draw(shape);
-}
-
-
-int main(void)
-{
- c_auto (Shapes, shapes)
- {
- Triangle* tri1 = Triangle_new((Point){5, 7}, (Point){12, 7}, (Point){12, 20});
- Polygon* pol1 = Polygon_new();
- Polygon* pol2 = Polygon_new();
-
- c_apply(p, Polygon_addPoint(pol1, *p), Point,
- {{50, 72}, {123, 73}, {127, 201}, {828, 333}});
-
- c_apply(p, Polygon_addPoint(pol2, *p), Point,
- {{5, 7}, {12, 7}, {12, 20}, {82, 33}, {17, 56}});
-
- Shapes_push(&shapes, &tri1->base);
- Shapes_push(&shapes, &pol1->base);
- Shapes_push(&shapes, &pol2->base);
-
- c_foreach (i, Shapes, shapes)
- testShape(*i.ref);
- }
-}
+// Demo of typesafe polymorphism in C99, using STC. + +#include <stdlib.h> +#include <stdio.h> +#include <stc/ccommon.h> + +#define c_dyn_ptr(T, s) \ + (&T##_api == (s)->api ? (T*)(s) : (T*)0) + +#define c_vtable(Api, T) \ + c_static_assert(offsetof(T, base) == 0); \ + static Api T##_api + +// Shape definition +// ============================================================ + +typedef struct { + float x, y; +} Point; + +typedef struct Shape Shape; + +struct ShapeAPI { + void (*drop)(Shape*); + void (*draw)(const Shape*); +}; + +struct Shape { + struct ShapeAPI* api; + uint32_t color; + uint16_t style; + uint8_t thickness; + uint8_t hardness; +}; + +void Shape_drop(Shape* shape) +{ + printf("base destructed\n"); +} + +void Shape_delete(Shape* shape) +{ + if (shape) { + shape->api->drop(shape); + c_free(shape); + } +} + +// Triangle implementation +// ============================================================ + +typedef struct { + Shape base; + Point p[3]; +} Triangle; + +c_vtable(struct ShapeAPI, Triangle); + + +Triangle* Triangle_new(Point a, Point b, Point c) +{ + return c_new(Triangle, {{.api=&Triangle_api}, .p={a, b, c}}); +} + +static void Triangle_draw(const Shape* shape) +{ + const Triangle* self = c_dyn_ptr(Triangle, shape); + printf("Triangle : (%g,%g), (%g,%g), (%g,%g)\n", + self->p[0].x, self->p[0].y, + self->p[1].x, self->p[1].y, + self->p[2].x, self->p[2].y); +} + +static struct ShapeAPI Triangle_api = { + .drop = Shape_drop, + .draw = Triangle_draw, +}; + +// Polygon implementation +// ============================================================ + +#define i_type PointVec +#define i_val Point +#include <stc/cstack.h> + +typedef struct { + Shape base; + PointVec points; +} Polygon; + +c_vtable(struct ShapeAPI, Polygon); + + +Polygon* Polygon_new(void) +{ + return c_new(Polygon, {{.api=&Polygon_api}, .points=PointVec_init()}); +} + +void Polygon_addPoint(Polygon* self, Point p) +{ + PointVec_push(&self->points, p); +} + +static void Polygon_drop(Shape* shape) +{ + Polygon* self = c_dyn_ptr(Polygon, shape); + printf("poly destructed\n"); + PointVec_drop(&self->points); + Shape_drop(shape); +} + +static void Polygon_draw(const Shape* shape) +{ + const Polygon* self = c_dyn_ptr(Polygon, shape); + printf("Polygon :"); + c_foreach (i, PointVec, self->points) + printf(" (%g,%g)", i.ref->x, i.ref->y); + puts(""); +} + +static struct ShapeAPI Polygon_api = { + .drop = Polygon_drop, + .draw = Polygon_draw, +}; + +// Test +// ============================================================ + +#define i_type Shapes +#define i_val Shape* +#define i_valdrop(x) Shape_delete(*x) +#include <stc/cstack.h> + +void testShape(const Shape* shape) +{ + shape->api->draw(shape); +} + + +int main(void) +{ + c_auto (Shapes, shapes) + { + Triangle* tri1 = Triangle_new((Point){5, 7}, (Point){12, 7}, (Point){12, 20}); + Polygon* pol1 = Polygon_new(); + Polygon* pol2 = Polygon_new(); + + c_apply(p, Polygon_addPoint(pol1, *p), Point, + {{50, 72}, {123, 73}, {127, 201}, {828, 333}}); + + c_apply(p, Polygon_addPoint(pol2, *p), Point, + {{5, 7}, {12, 7}, {12, 20}, {82, 33}, {17, 56}}); + + Shapes_push(&shapes, &tri1->base); + Shapes_push(&shapes, &pol1->base); + Shapes_push(&shapes, &pol2->base); + + c_foreach (i, Shapes, shapes) + testShape(*i.ref); + } +} diff --git a/examples/shape.cpp b/examples/shape.cpp index b451b5ba..ea1f53d2 100644 --- a/examples/shape.cpp +++ b/examples/shape.cpp @@ -1,122 +1,122 @@ -// Demo of polymorphism in C++
-
-#include <iostream>
-#include <memory>
-#include <vector>
-
-// Shape definition
-// ============================================================
-
-struct Point {
- float x, y;
-};
-
-std::ostream& operator<<(std::ostream& os, const Point& p) {
- os << " (" << p.x << "," << p.y << ")";
- return os;
-}
-
-struct Shape {
- virtual ~Shape();
- virtual void draw() const = 0;
-
- uint32_t color;
- uint16_t style;
- uint8_t thickness;
- uint8_t hardness;
-};
-
-Shape::~Shape()
-{
- std::cout << "base destructed" << std::endl;
-}
-
-// Triangle implementation
-// ============================================================
-
-struct Triangle : public Shape
-{
- Triangle(Point a, Point b, Point c);
- void draw() const override;
-
- private: Point p[3];
-};
-
-
-Triangle::Triangle(Point a, Point b, Point c)
- : p{a, b, c} {}
-
-void Triangle::draw() const
-{
- std::cout << "Triangle :"
- << p[0] << p[1] << p[2]
- << std::endl;
-}
-
-
-// Polygon implementation
-// ============================================================
-
-
-struct Polygon : public Shape
-{
- ~Polygon();
- void draw() const override;
- void addPoint(const Point& p);
-
- private: std::vector<Point> points;
-};
-
-
-void Polygon::addPoint(const Point& p)
-{
- points.push_back(p);
-}
-
-Polygon::~Polygon()
-{
- std::cout << "poly destructed" << std::endl;
-}
-
-void Polygon::draw() const
-{
- std::cout << "Polygon :";
- for (auto& p : points)
- std::cout << p ;
- std::cout << std::endl;
-}
-
-
-// Test
-// ============================================================
-
-void testShape(const Shape* shape)
-{
- shape->draw();
-}
-
-#include <array>
-
-int main(void)
-{
- std::vector<std::unique_ptr<Shape>> shapes;
-
- auto tri1 = std::make_unique<Triangle>(Point{5, 7}, Point{12, 7}, Point{12, 20});
- auto pol1 = std::make_unique<Polygon>();
- auto pol2 = std::make_unique<Polygon>();
-
- for (auto& p: std::array<Point, 4>
- {{{50, 72}, {123, 73}, {127, 201}, {828, 333}}})
- pol1->addPoint(p);
-
- for (auto& p: std::array<Point, 5>
- {{{5, 7}, {12, 7}, {12, 20}, {82, 33}, {17, 56}}})
- pol2->addPoint(p);
-
- shapes.push_back(std::move(tri1));
- shapes.push_back(std::move(pol1));
- shapes.push_back(std::move(pol2));
-
- for (auto& shape: shapes)
- testShape(shape.get());
-}
+// Demo of polymorphism in C++ + +#include <iostream> +#include <memory> +#include <vector> + +// Shape definition +// ============================================================ + +struct Point { + float x, y; +}; + +std::ostream& operator<<(std::ostream& os, const Point& p) { + os << " (" << p.x << "," << p.y << ")"; + return os; +} + +struct Shape { + virtual ~Shape(); + virtual void draw() const = 0; + + uint32_t color; + uint16_t style; + uint8_t thickness; + uint8_t hardness; +}; + +Shape::~Shape() +{ + std::cout << "base destructed" << std::endl; +} + +// Triangle implementation +// ============================================================ + +struct Triangle : public Shape +{ + Triangle(Point a, Point b, Point c); + void draw() const override; + + private: Point p[3]; +}; + + +Triangle::Triangle(Point a, Point b, Point c) + : p{a, b, c} {} + +void Triangle::draw() const +{ + std::cout << "Triangle :" + << p[0] << p[1] << p[2] + << std::endl; +} + + +// Polygon implementation +// ============================================================ + + +struct Polygon : public Shape +{ + ~Polygon(); + void draw() const override; + void addPoint(const Point& p); + + private: std::vector<Point> points; +}; + + +void Polygon::addPoint(const Point& p) +{ + points.push_back(p); +} + +Polygon::~Polygon() +{ + std::cout << "poly destructed" << std::endl; +} + +void Polygon::draw() const +{ + std::cout << "Polygon :"; + for (auto& p : points) + std::cout << p ; + std::cout << std::endl; +} + + +// Test +// ============================================================ + +void testShape(const Shape* shape) +{ + shape->draw(); +} + +#include <array> + +int main(void) +{ + std::vector<std::unique_ptr<Shape>> shapes; + + auto tri1 = std::make_unique<Triangle>(Point{5, 7}, Point{12, 7}, Point{12, 20}); + auto pol1 = std::make_unique<Polygon>(); + auto pol2 = std::make_unique<Polygon>(); + + for (auto& p: std::array<Point, 4> + {{{50, 72}, {123, 73}, {127, 201}, {828, 333}}}) + pol1->addPoint(p); + + for (auto& p: std::array<Point, 5> + {{{5, 7}, {12, 7}, {12, 20}, {82, 33}, {17, 56}}}) + pol2->addPoint(p); + + shapes.push_back(std::move(tri1)); + shapes.push_back(std::move(pol1)); + shapes.push_back(std::move(pol2)); + + for (auto& shape: shapes) + testShape(shape.get()); +} diff --git a/examples/sidebyside.cpp b/examples/sidebyside.cpp index 89446b23..4d63496b 100644 --- a/examples/sidebyside.cpp +++ b/examples/sidebyside.cpp @@ -1,54 +1,54 @@ -#include <iostream>
-#include <map>
-#include <string>
-
-#define i_key_str
-#define i_val int
-#define i_tag si
-#include <stc/cmap.h>
-
-#define i_key int
-#define i_val int
-#define i_tag ii
-#include <stc/csmap.h>
-
-int main() {
- {
- std::map<std::string, int> food =
- {{"burger", 5}, {"pizza", 12}, {"steak", 15}};
-
- for (auto i: food)
- std::cout << i.first << ", " << i.second << std::endl;
- std::cout << std::endl;
- }
- c_auto (cmap_si, food)
- {
- c_apply(v, cmap_si_emplace(&food, c_pair(v)), cmap_si_raw,
- {{"burger", 5}, {"pizza", 12}, {"steak", 15}});
-
- c_foreach (i, cmap_si, food)
- printf("%s, %d\n", i.ref->first.str, i.ref->second);
- puts("");
- }
-
- {
- std::map<int, int> hist;
- ++ hist.emplace(12, 100).first->second;
- ++ hist.emplace(13, 100).first->second;
- ++ hist.emplace(12, 100).first->second;
-
- for (auto i: hist)
- std::cout << i.first << ", " << i.second << std::endl;
- std::cout << std::endl;
- }
- c_auto (csmap_ii, hist)
- {
- ++ csmap_ii_insert(&hist, 12, 100).ref->second;
- ++ csmap_ii_insert(&hist, 13, 100).ref->second;
- ++ csmap_ii_insert(&hist, 12, 100).ref->second;
-
- c_foreach (i, csmap_ii, hist)
- printf("%d, %d\n", i.ref->first, i.ref->second);
- puts("");
- }
-}
+#include <iostream> +#include <map> +#include <string> + +#define i_key_str +#define i_val int +#define i_tag si +#include <stc/cmap.h> + +#define i_key int +#define i_val int +#define i_tag ii +#include <stc/csmap.h> + +int main() { + { + std::map<std::string, int> food = + {{"burger", 5}, {"pizza", 12}, {"steak", 15}}; + + for (auto i: food) + std::cout << i.first << ", " << i.second << std::endl; + std::cout << std::endl; + } + c_auto (cmap_si, food) + { + c_apply(v, cmap_si_emplace(&food, c_pair(v)), cmap_si_raw, + {{"burger", 5}, {"pizza", 12}, {"steak", 15}}); + + c_foreach (i, cmap_si, food) + printf("%s, %d\n", i.ref->first.str, i.ref->second); + puts(""); + } + + { + std::map<int, int> hist; + ++ hist.emplace(12, 100).first->second; + ++ hist.emplace(13, 100).first->second; + ++ hist.emplace(12, 100).first->second; + + for (auto i: hist) + std::cout << i.first << ", " << i.second << std::endl; + std::cout << std::endl; + } + c_auto (csmap_ii, hist) + { + ++ csmap_ii_insert(&hist, 12, 100).ref->second; + ++ csmap_ii_insert(&hist, 13, 100).ref->second; + ++ csmap_ii_insert(&hist, 12, 100).ref->second; + + c_foreach (i, csmap_ii, hist) + printf("%d, %d\n", i.ref->first, i.ref->second); + puts(""); + } +} diff --git a/examples/splitstr.c b/examples/splitstr.c index 0cd48067..a155830c 100644 --- a/examples/splitstr.c +++ b/examples/splitstr.c @@ -1,39 +1,39 @@ -#define i_implement
-#include <stc/cstr.h>
-#define i_implement
-#include <stc/csview.h>
-#define i_val_str
-#include <stc/cvec.h>
-
-void print_split(csview str, csview sep)
-{
- size_t pos = 0;
- while (pos != str.size) {
- csview tok = csview_token(str, sep, &pos);
- // print non-null-terminated csview
- printf("[%" c_PRIsv "]\n", c_ARGsv(tok));
- }
-}
-
-cvec_str string_split(csview str, csview sep)
-{
- cvec_str vec = cvec_str_init();
- size_t pos = 0;
- while (pos != str.size) {
- csview tok = csview_token(str, sep, &pos);
- cvec_str_push_back(&vec, cstr_from_sv(tok));
- }
- return vec;
-}
-
-int main()
-{
- print_split(c_sv("//This is a//double-slash//separated//string"), c_sv("//"));
- puts("");
- print_split(c_sv("This has no matching separator"), c_sv("xx"));
- puts("");
-
- c_autovar (cvec_str v = string_split(c_sv("Split,this,,string,now,"), c_sv(",")), cvec_str_drop(&v))
- c_foreach (i, cvec_str, v)
- printf("[%s]\n", cstr_str(i.ref));
-}
+#define i_implement +#include <stc/cstr.h> +#define i_implement +#include <stc/csview.h> +#define i_val_str +#include <stc/cvec.h> + +void print_split(csview str, csview sep) +{ + size_t pos = 0; + while (pos != str.size) { + csview tok = csview_token(str, sep, &pos); + // print non-null-terminated csview + printf("[%" c_PRIsv "]\n", c_ARGsv(tok)); + } +} + +cvec_str string_split(csview str, csview sep) +{ + cvec_str vec = cvec_str_init(); + size_t pos = 0; + while (pos != str.size) { + csview tok = csview_token(str, sep, &pos); + cvec_str_push_back(&vec, cstr_from_sv(tok)); + } + return vec; +} + +int main() +{ + print_split(c_sv("//This is a//double-slash//separated//string"), c_sv("//")); + puts(""); + print_split(c_sv("This has no matching separator"), c_sv("xx")); + puts(""); + + c_autovar (cvec_str v = string_split(c_sv("Split,this,,string,now,"), c_sv(",")), cvec_str_drop(&v)) + c_foreach (i, cvec_str, v) + printf("[%s]\n", cstr_str(i.ref)); +} diff --git a/examples/sso_map.c b/examples/sso_map.c index 53fac3e3..823398e1 100644 --- a/examples/sso_map.c +++ b/examples/sso_map.c @@ -1,18 +1,18 @@ -#define i_implement
-#include <stc/cstr.h>
-#define i_key_str
-#define i_val_str
-#include <stc/cmap.h>
-
-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.");
-
- c_forpair (k, v, cmap_str, m)
- printf("%s: '%s' Len=%" PRIuMAX ", Is long: %s\n",
- cstr_str(_.k), cstr_str(_.v), cstr_size(*_.v),
- cstr_is_long(_.v)?"true":"false");
- }
-}
+#define i_implement +#include <stc/cstr.h> +#define i_key_str +#define i_val_str +#include <stc/cmap.h> + +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."); + + c_forpair (k, v, cmap_str, m) + printf("%s: '%s' Len=%" PRIuMAX ", Is long: %s\n", + cstr_str(_.k), cstr_str(_.v), cstr_size(*_.v), + cstr_is_long(_.v)?"true":"false"); + } +} diff --git a/examples/stack.c b/examples/stack.c index 29b39aef..ca809c97 100644 --- a/examples/stack.c +++ b/examples/stack.c @@ -1,29 +1,29 @@ -
-#include <stdio.h>
-
-#define i_tag i
-#define i_val int
-#include <stc/cstack.h>
-
-#define i_tag c
-#define i_val char
-#include <stc/cstack.h>
-
-int main() {
- c_auto (cstack_i, stack)
- c_auto (cstack_c, chars)
- {
- c_forrange (i, int, 101)
- cstack_i_push(&stack, i*i);
-
- printf("%d\n", *cstack_i_top(&stack));
-
- c_forrange (i, int, 90)
- cstack_i_pop(&stack);
-
- c_foreach (i, cstack_i, stack)
- printf(" %d", *i.ref);
- puts("");
- printf("top: %d\n", *cstack_i_top(&stack));
- }
-}
+ +#include <stdio.h> + +#define i_tag i +#define i_val int +#include <stc/cstack.h> + +#define i_tag c +#define i_val char +#include <stc/cstack.h> + +int main() { + c_auto (cstack_i, stack) + c_auto (cstack_c, chars) + { + c_forrange (i, int, 101) + cstack_i_push(&stack, i*i); + + printf("%d\n", *cstack_i_top(&stack)); + + c_forrange (i, int, 90) + cstack_i_pop(&stack); + + c_foreach (i, cstack_i, stack) + printf(" %d", *i.ref); + puts(""); + printf("top: %d\n", *cstack_i_top(&stack)); + } +} diff --git a/examples/sview_split.c b/examples/sview_split.c index 8c3d7120..2c7ce395 100644 --- a/examples/sview_split.c +++ b/examples/sview_split.c @@ -1,21 +1,21 @@ -#define STC_IMPLEMENT
-#include <stc/cstr.h>
-#include <stc/csview.h>
-
-int main()
-{
- // No memory allocations or string length calculations!
- const csview date = c_sv("2021/03/12");
- size_t pos = 0;
- const csview year = csview_token(date, c_sv("/"), &pos);
- const csview month = csview_token(date, c_sv("/"), &pos);
- const csview day = csview_token(date, c_sv("/"), &pos);
-
- printf("%" c_PRIsv ", %" c_PRIsv ", %" c_PRIsv "\n",
- c_ARGsv(year), c_ARGsv(month), c_ARGsv(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));
- }
-}
+#define STC_IMPLEMENT +#include <stc/cstr.h> +#include <stc/csview.h> + +int main() +{ + // No memory allocations or string length calculations! + const csview date = c_sv("2021/03/12"); + size_t pos = 0; + const csview year = csview_token(date, c_sv("/"), &pos); + const csview month = csview_token(date, c_sv("/"), &pos); + const csview day = csview_token(date, c_sv("/"), &pos); + + printf("%" c_PRIsv ", %" c_PRIsv ", %" c_PRIsv "\n", + c_ARGsv(year), c_ARGsv(month), c_ARGsv(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)); + } +} diff --git a/examples/unordered_map.c b/examples/unordered_map.c index 7af6fa0a..c4a05c76 100644 --- a/examples/unordered_map.c +++ b/examples/unordered_map.c @@ -1,64 +1,64 @@ -// https://iq.opengenus.org/containers-cpp-stl/
-
-#define i_key int
-#define i_val int
-#include <stc/csmap.h>
-#include <stdio.h>
-
-int main()
-{
-
- // empty map containers
- c_auto (csmap_int, gquiz1, gquiz2)
- {
- // insert elements in random order
- csmap_int_insert(&gquiz1, 2, 30);
- csmap_int_insert(&gquiz1, 4, 20);
- csmap_int_insert(&gquiz1, 7, 10);
- csmap_int_insert(&gquiz1, 5, 50);
- csmap_int_insert(&gquiz1, 3, 60);
- csmap_int_insert(&gquiz1, 1, 40);
- csmap_int_insert(&gquiz1, 6, 50);
-
- // printing map gquiz1
- printf("\nThe map gquiz1 is :\n\tKEY\tELEMENT\n");
- c_foreach (itr, csmap_int, gquiz1)
- printf("\t%d\t%d\n", itr.ref->first, itr.ref->second);
- printf("\n");
-
- // assigning the elements from gquiz1 to gquiz2
- c_foreach (i, csmap_int, gquiz1)
- csmap_int_insert(&gquiz2, i.ref->first, i.ref->second);
-
- // print all elements of the map gquiz2
- printf("\nThe map gquiz2 is :\n\tKEY\tELEMENT\n");
- c_foreach (itr, csmap_int, gquiz2)
- printf("\t%d\t%d\n", itr.ref->first, itr.ref->second);
- printf("\n");
-
- // remove all elements up to element with key=3 in gquiz2
- printf("\ngquiz2 after removal of elements less than key=3 :\n");
- printf("\tKEY\tELEMENT\n");
- csmap_int_erase_range(&gquiz2, csmap_int_begin(&gquiz2),
- csmap_int_find(&gquiz2, 3));
- c_foreach (itr, csmap_int, gquiz2)
- printf("\t%d\t%d\n", itr.ref->first, itr.ref->second);
- printf("\n");
-
- // remove all elements with key = 4
- int num = csmap_int_erase(&gquiz2, 4);
- printf("\ngquiz2.erase(4) : %d removed\n", num);
- printf("\tKEY\tELEMENT\n");
- c_foreach (itr, csmap_int, gquiz2)
- printf("\t%d\t%d\n", itr.ref->first, itr.ref->second);
- printf("\n");
-
- // lower bound and upper bound for map gquiz1 key = 5
- printf("gquiz1.lower_bound(5) : ");
- printf("\tKEY = %d\t", csmap_int_lower_bound(&gquiz1, 5).ref->first);
- printf("\tELEMENT = %d\n", csmap_int_lower_bound(&gquiz1, 5).ref->second);
- printf("gquiz1.upper_bound(5) : ");
- printf("\tKEY = %d\t", csmap_int_lower_bound(&gquiz1, 5+1).ref->first);
- printf("\tELEMENT = %d\n", csmap_int_lower_bound(&gquiz1, 5+1).ref->second);
- }
-}
+// https://iq.opengenus.org/containers-cpp-stl/ + +#define i_key int +#define i_val int +#include <stc/csmap.h> +#include <stdio.h> + +int main() +{ + + // empty map containers + c_auto (csmap_int, gquiz1, gquiz2) + { + // insert elements in random order + csmap_int_insert(&gquiz1, 2, 30); + csmap_int_insert(&gquiz1, 4, 20); + csmap_int_insert(&gquiz1, 7, 10); + csmap_int_insert(&gquiz1, 5, 50); + csmap_int_insert(&gquiz1, 3, 60); + csmap_int_insert(&gquiz1, 1, 40); + csmap_int_insert(&gquiz1, 6, 50); + + // printing map gquiz1 + printf("\nThe map gquiz1 is :\n\tKEY\tELEMENT\n"); + c_foreach (itr, csmap_int, gquiz1) + printf("\t%d\t%d\n", itr.ref->first, itr.ref->second); + printf("\n"); + + // assigning the elements from gquiz1 to gquiz2 + c_foreach (i, csmap_int, gquiz1) + csmap_int_insert(&gquiz2, i.ref->first, i.ref->second); + + // print all elements of the map gquiz2 + printf("\nThe map gquiz2 is :\n\tKEY\tELEMENT\n"); + c_foreach (itr, csmap_int, gquiz2) + printf("\t%d\t%d\n", itr.ref->first, itr.ref->second); + printf("\n"); + + // remove all elements up to element with key=3 in gquiz2 + printf("\ngquiz2 after removal of elements less than key=3 :\n"); + printf("\tKEY\tELEMENT\n"); + csmap_int_erase_range(&gquiz2, csmap_int_begin(&gquiz2), + csmap_int_find(&gquiz2, 3)); + c_foreach (itr, csmap_int, gquiz2) + printf("\t%d\t%d\n", itr.ref->first, itr.ref->second); + printf("\n"); + + // remove all elements with key = 4 + int num = csmap_int_erase(&gquiz2, 4); + printf("\ngquiz2.erase(4) : %d removed\n", num); + printf("\tKEY\tELEMENT\n"); + c_foreach (itr, csmap_int, gquiz2) + printf("\t%d\t%d\n", itr.ref->first, itr.ref->second); + printf("\n"); + + // lower bound and upper bound for map gquiz1 key = 5 + printf("gquiz1.lower_bound(5) : "); + printf("\tKEY = %d\t", csmap_int_lower_bound(&gquiz1, 5).ref->first); + printf("\tELEMENT = %d\n", csmap_int_lower_bound(&gquiz1, 5).ref->second); + printf("gquiz1.upper_bound(5) : "); + printf("\tKEY = %d\t", csmap_int_lower_bound(&gquiz1, 5+1).ref->first); + printf("\tELEMENT = %d\n", csmap_int_lower_bound(&gquiz1, 5+1).ref->second); + } +} diff --git a/examples/unordered_set.c b/examples/unordered_set.c index 9ecd59fe..99a9da49 100644 --- a/examples/unordered_set.c +++ b/examples/unordered_set.c @@ -1,43 +1,43 @@ -// https://iq.opengenus.org/containers-cpp-stl/
-// C program to demonstrate various function of stc cset
-#define i_implement
-#include <stc/cstr.h>
-#define i_key_str
-#include <stc/cset.h>
-
-int main()
-{
- // declaring set for storing string data-type
- c_auto (cset_str, stringSet)
- {
- // inserting various string, same string will be stored
- // once in set
- cset_str_emplace(&stringSet, "code");
- cset_str_emplace(&stringSet, "in");
- cset_str_emplace(&stringSet, "C");
- cset_str_emplace(&stringSet, "is");
- cset_str_emplace(&stringSet, "fast");
-
- const char* key = "slow";
-
- // find returns end iterator if key is not found,
- // else it returns iterator to that key
-
- if (cset_str_find(&stringSet, key).ref == cset_str_end(&stringSet).ref)
- printf("\"%s\" not found\n", key);
- else
- printf("Found \"%s\"\n", key);
-
- key = "C";
- if (!cset_str_contains(&stringSet, key))
- printf("\"%s\" not found\n", key);
- else
- printf("Found \"%s\"\n", key);
-
- // now iterating over whole set and printing its
- // content
- printf("All elements :\n");
- c_foreach (itr, cset_str, stringSet)
- printf("%s\n", cstr_str(itr.ref));
- }
-}
+// https://iq.opengenus.org/containers-cpp-stl/ +// C program to demonstrate various function of stc cset +#define i_implement +#include <stc/cstr.h> +#define i_key_str +#include <stc/cset.h> + +int main() +{ + // declaring set for storing string data-type + c_auto (cset_str, stringSet) + { + // inserting various string, same string will be stored + // once in set + cset_str_emplace(&stringSet, "code"); + cset_str_emplace(&stringSet, "in"); + cset_str_emplace(&stringSet, "C"); + cset_str_emplace(&stringSet, "is"); + cset_str_emplace(&stringSet, "fast"); + + const char* key = "slow"; + + // find returns end iterator if key is not found, + // else it returns iterator to that key + + if (cset_str_find(&stringSet, key).ref == cset_str_end(&stringSet).ref) + printf("\"%s\" not found\n", key); + else + printf("Found \"%s\"\n", key); + + key = "C"; + if (!cset_str_contains(&stringSet, key)) + printf("\"%s\" not found\n", key); + else + printf("Found \"%s\"\n", key); + + // now iterating over whole set and printing its + // content + printf("All elements :\n"); + c_foreach (itr, cset_str, stringSet) + printf("%s\n", cstr_str(itr.ref)); + } +} |
