diff --git a/README.md b/README.md index 46a86a98..c49c2a6f 100644 --- a/README.md +++ b/README.md @@ -280,8 +280,8 @@ int main(void) ){ enum{N = 5}; int nums[N] = {10, 20, 30, 40, 50}; - struct Point pts[N] = { {10, 1}, {20, 2}, {30, 3}, {40, 4}, {50, 5} }; - int pairs[N][2] = { {20, 2}, {10, 1}, {30, 3}, {40, 4}, {50, 5} }; + struct Point pts[N] = {{10, 1}, {20, 2}, {30, 3}, {40, 4}, {50, 5}}; + int pairs[N][2] = {{20, 2}, {10, 1}, {30, 3}, {40, 4}, {50, 5}}; // Add some elements to each container for (int i = 0; i < N; ++i) { diff --git a/docs/algorithm_api.md b/docs/algorithm_api.md index 687801c2..d3e8ebb4 100644 --- a/docs/algorithm_api.md +++ b/docs/algorithm_api.md @@ -25,7 +25,7 @@ STC contains many generic algorithms and flow control abstactions. #define i_type IMap, int, int #include "stc/smap.h" // ... -IMap map = c_init(IMap, { {23,1}, {3,2}, {7,3}, {5,4}, {12,5} }); +IMap map = c_init(IMap, {{23,1}, {3,2}, {7,3}, {5,4}, {12,5}}); c_foreach (i, IMap, map) printf(" %d", i.ref->first); @@ -43,10 +43,10 @@ c_foreach (i, IMap, iter, IMap_end(&map)) // iterate first 3 with an index count enumeration c_foreach_n (i, IMap, map, 3) - printf(" %zd:(%d %d)", i_count, i.ref->first, i.ref->second); + printf(" %zd:(%d %d)", i_index, i.ref->first, i.ref->second); // 0:(3 2) 1:(5 4) 2:(7 3) -// iterate maps with "structured binding": +// iterate a map using "structured binding" of the key and val pair: c_foreach_kv (id, count, IMap, map) printf(" (%d %d)", *id, *count); ``` @@ -62,7 +62,7 @@ c_foritems (i, int, {4, 5, 6, 7}) list_i_push_back(&lst, *i.ref); // insert in existing map -c_foritems (i, hmap_ii_value, { {4, 5}, {6, 7} }) +c_foritems (i, hmap_ii_value, {{4, 5}, {6, 7}}) hmap_ii_insert(&map, i.ref->first, i.ref->second); // string literals pushed to a stack of cstr elements: @@ -216,48 +216,17 @@ int main(void) ## Generic algorithms -
-Generic container operations - -### c_init, c_push, c_drop - -- **c_init** - construct any container from an initializer list -- **c_push** - push values onto any container from an initializer list -- **c_drop** - drop (destroy) multiple containers of the same type -```c -#include -#define i_type Vec, int -#include "stc/vec.h" - -#define i_type Map, int, int -#include "stc/hmap.h" -int main(void) { - Vec vec = c_init(Vec, {1, 2, 3, 4, 5, 6}); - Vec vec2 = c_init(Vec, {42, 43, 44, 45, 46}); - Map map = c_init(Map, {{1, 2}, {3, 4}, {5, 6}}); - - c_push(Vec, &vec, {7, 8, 9, 10, 11, 12}); - c_push(Map, &map, {{7, 8}, {9, 10}, {11, 12}}); - - c_foreach (i, Vec, vec) printf("%d ", *i.ref); puts(""); - c_foreach_kv(k, v, Map, map) printf("%d:%d ", *k, *v); puts(""); - - c_drop(Vec, &vec, &vec2); - c_drop(Map, &map); -} -``` -
c_func - Function with on-the-fly defined return type ### c_func -A convenient macro for defining functions mith one or multiple return values, e.g. for errors. +A convenient macro for defining functions with one or multiple return values, e.g. for errors. ```c Vec get_data(void) { return c_init(Vec, {1, 2, 3, 4, 5, 6}); } - +// same as get_data(): c_func (get_data1,(void), ->, Vec) { return c_init(Vec, {1, 2, 3, 4, 5, 6}); } @@ -280,6 +249,54 @@ c_func (load_data,(const char* fname), ->, struct {Vec out; int err;}) { ```
+c_init, c_push, c_drop - Generic container operations + +### c_init, c_push, c_drop + +- **c_init** - construct any container from an initializer list +- **c_push** - push values onto any container from an initializer list +- **c_drop** - drop (destroy) multiple containers of the same type + +[ [Run this code](https://godbolt.org/z/Gr1Y4MvMb) ] +```c +#include +#define i_type Vec, int +#include "stc/vec.h" + +#define i_type Map, int, int +#include "stc/hmap.h" + +c_func (split_map,(Map m), ->, struct {Vec keys, vals;}) { + split_map_result res = {0}; + c_foreach_kv (k, v, Map, m) { + Vec_push(&res.keys, *k); + Vec_push(&res.vals, *v); + } + return res; +} + +int main(void) { + Vec vec = c_init(Vec, {1, 2, 3, 4, 5, 6}); + Map map = c_init(Map, {{1, 2}, {3, 4}, {5, 6}}); + + c_push(Vec, &vec, {7, 8, 9, 10, 11, 12}); + c_push(Map, &map, {{7, 8}, {9, 10}, {11, 12}}); + + c_foreach (i, Vec, vec) printf("%d ", *i.ref); + puts(""); + c_foreach_kv(k, v, Map, map) printf("{%d %d} ", *k, *v); + puts(""); + + split_map_result res = split_map(map); + c_foreach (i, Vec, res.vals) printf("%d ", *i.ref); + puts(""); + + c_drop(Vec, &vec, &res.keys, &res.vals); + c_drop(Map, &map); +} +``` +
+
c_find, c_copy, c_erase - Container operations with custom predicate ### c_find_if, c_find_reverse_if @@ -352,7 +369,7 @@ int main(void) puts(""); // Search a sorted map from it1, for the first string containing "hello" and erase it: - Map map = c_init(Map, { {"yes",1}, {"no",2}, {"say hello from me",3}, {"goodbye",4} }); + Map map = c_init(Map, {{"yes",1}, {"no",2}, {"say hello from me",3}, {"goodbye",4}}); Map_iter res, it1 = Map_begin(&map); c_find_if(Map, it1, Map_end(&map), &res, cstr_contains(&value->first, "hello")); @@ -369,7 +386,7 @@ int main(void) ```
-c_all_of, c_any_of, c_none_of - Generic container operations +c_all_of, c_any_of, c_none_of - Boolean container operations ### c_all_of, c_any_of, c_none_of Test a container/range using a predicate. ***result*** is output and must be declared prior to call. @@ -579,4 +596,4 @@ int main(void) ```
---- \ No newline at end of file +--- diff --git a/docs/hmap_api.md b/docs/hmap_api.md index dea3394d..40b34f1a 100644 --- a/docs/hmap_api.md +++ b/docs/hmap_api.md @@ -176,7 +176,7 @@ int main(void) IDMap idnames = {0}; - c_foritems (i, IDMap_raw, { {100, "Red"}, {110, "Blue"} }) + c_foritems (i, IDMap_raw, {{100, "Red"}, {110, "Blue"}}) IDMap_emplace(&idnames, i.ref->first, i.ref->second); // replace existing mapped value: diff --git a/docs/smap_api.md b/docs/smap_api.md index 987a6a6c..8638d102 100644 --- a/docs/smap_api.md +++ b/docs/smap_api.md @@ -194,7 +194,7 @@ This example uses a smap with cstr as mapped value. int main(void) { uint32_t col = 0xcc7744ff; - IDSMap idnames = c_init(IDSMap, { {100, "Red"}, {110, "Blue"} }); + IDSMap idnames = c_init(IDSMap, {{100, "Red"}, {110, "Blue"}}); // Assign/overwrite an existing mapped value with a const char* IDSMap_emplace_or_assign(&idnames, 110, "White");