diff options
| author | Tyge Løvset <[email protected]> | 2022-08-06 17:48:06 +0200 |
|---|---|---|
| committer | Tyge Løvset <[email protected]> | 2022-08-06 17:48:06 +0200 |
| commit | 618b5704e6f85cfe1b6e5c9c9373abe76a8bb628 (patch) | |
| tree | 4e25a538c8ba3fd58bb25b90ff6dc54adfb31aa4 /docs | |
| parent | 927fa8093ea0bc1e25586e60c47cf1dd8a311d9e (diff) | |
| download | STC-modified-618b5704e6f85cfe1b6e5c9c9373abe76a8bb628.tar.gz STC-modified-618b5704e6f85cfe1b6e5c9c9373abe76a8bb628.zip | |
c_apply() deprecated: replaced with c_forarray() macro. Updated and improved README.md docs.
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/carc_api.md | 15 | ||||
| -rw-r--r-- | docs/cbox_api.md | 4 | ||||
| -rw-r--r-- | docs/ccommon_api.md | 122 | ||||
| -rw-r--r-- | docs/cdeq_api.md | 4 | ||||
| -rw-r--r-- | docs/clist_api.md | 7 | ||||
| -rw-r--r-- | docs/cmap_api.md | 10 | ||||
| -rw-r--r-- | docs/cset_api.md | 10 | ||||
| -rw-r--r-- | docs/csmap_api.md | 13 | ||||
| -rw-r--r-- | docs/csset_api.md | 9 | ||||
| -rw-r--r-- | docs/cvec_api.md | 3 |
10 files changed, 115 insertions, 82 deletions
diff --git a/docs/carc_api.md b/docs/carc_api.md index 534e3da3..2604e13a 100644 --- a/docs/carc_api.md +++ b/docs/carc_api.md @@ -100,25 +100,26 @@ int main() // POPULATE the stack with shared pointers to Map: Map *map; map = Stack_push(&stack, Arc_make(Map_init()))->get; - c_apply(v, Map_emplace(map, c_pair(v)), Map_raw, { + c_forarray (Map_raw, v, { {"Joey", 1990}, {"Mary", 1995}, - {"Joanna", 1992} - }); + {"Joanna", 1992}, + }) Map_emplace(map, v->first, v->second); + map = Stack_push(&stack, Arc_make(Map_init()))->get; - c_apply(v, Map_emplace(map, c_pair(v)), Map_raw, { + c_forarray (Map_raw, v, { {"Rosanna", 2001}, {"Brad", 1999}, {"Jack", 1980} - }); + }) Map_emplace(map, v->first, v->second); // POPULATE the list: map = List_push_back(&list, Arc_make(Map_init()))->get; - c_apply(v, Map_emplace(map, c_pair(v)), Map_raw, { + c_forarray (Map_raw, v, { {"Steve", 1979}, {"Rick", 1974}, {"Tracy", 2003} - }); + }) Map_emplace(map, v->first, v->second); // Share two Maps from the stack with the list by cloning(=sharing) the carc: List_push_back(&list, Arc_clone(stack.data[0])); diff --git a/docs/cbox_api.md b/docs/cbox_api.md index 4087ffa3..1119d930 100644 --- a/docs/cbox_api.md +++ b/docs/cbox_api.md @@ -84,10 +84,10 @@ int main() c_auto (IVec, vec) // declare and init vec, call drop at scope exit c_auto (ISet, set) // similar { - c_apply(v, IVec_push(&vec, *v), IBox, { + c_forarray (IBox, v, { IBox_make(2021), IBox_make(2012), IBox_make(2022), IBox_make(2015), - }); + }) IVec_push(&vec, *v); printf("vec:"); c_foreach (i, IVec, vec) diff --git a/docs/ccommon_api.md b/docs/ccommon_api.md index 1a9fb30e..61791a20 100644 --- a/docs/ccommon_api.md +++ b/docs/ccommon_api.md @@ -13,7 +13,7 @@ The **checkauto** utility described below, ensures that the `c_auto*` macros are | `c_autovar (Type var=init, end...)` | Declare `var`. Defer `end...` to end of block | | `c_autoscope (init, end...)` | Execute `init`. Defer `end...` to end of block | | `c_autodefer (end...)` | Defer `end...` to end of block | -| `c_breakauto;` | Break out of a `c_auto*`-block/scope without memleak | +| `c_breakauto` or `continue` | Break out of a `c_auto*`-block/scope without memleak | For multiple variables, use either multiple **c_autovar** in sequence, or declare variable outside scope and use **c_autoscope**. Also, **c_auto** support up to 4 variables. @@ -84,44 +84,82 @@ int main() printf("%s\n", cstr_str(i.ref)); } ``` -### The checkauto utility program (for RAII) +### The **checkauto** utility program (for RAII) The **checkauto** program will check the source code for any misuses of the `c_auto*` macros which may lead to resource leakages. The `c_auto*`- macros are implemented as one-time executed **for-loops**, so any `return` or `break` appearing within such a block will lead to resource leaks, as it will disable -the cleanup/drop method to be called. However, a `break` may (originally) been intended to break the immediate -loop/switch outside the `c_auto` scope, so it would not work as intended in any case. The **checkauto** -tool will report any such misusages. In general, one should therefore first break out of any inner loops -with `break`, then use `c_breakauto` to break out of the `c_auto` scope(s). After this `return` may be used. +the cleanup/drop method to be called. A `break` may originally be intended to break a loop or switch +outside the `c_auto` scope. -Note that this is not a particular issue with the `c_auto*`-macros, as one must always make sure to unwind -temporary allocated resources before a `return` in C. However, by using `c_auto*`-macros, +NOTE: One must always make sure to unwind temporary allocated resources before a `return` in C. However, by using `c_auto*`-macros, - it is much easier to automatically detect misplaced return/break between resource acquisition and destruction. - it prevents forgetting to call the destructor at the end. + +The **checkauto** utility will report any misusages. The following example shows how to correctly break/return +from a `c_auto` scope: ```c -for (int i = 0; i<n; ++i) { - c_auto (List, list) { - List_push_back(&list, i); - if (cond1()) - break; // checkauto: Error - for (j = 0; j<m; ++j) { + int flag = 0; + for (int i = 0; i<n; ++i) { + c_auto (cstr, text) + c_auto (List, list) + { + for (int j = 0; j<m; ++j) { + List_push_back(&list, i*j); + if (cond1()) + break; // OK: breaks current for-loop only + } + // WRONG: if (cond2()) - break; // OK (breaks for-loop only) + break; // checkauto ERROR! break inside c_auto. + + if (cond3()) + return -1; // checkauto ERROR! return inside c_auto + + // CORRECT: + if (cond2()) { + flag = 1; // flag to break outer for-loop + continue; // cleanup and leave c_auto block + } + if (cond3()) { + flag = -1; // return -1 + continue; // cleanup and leave c_auto block + } + ... } - if (cond3()) - return; // checkauto: Error - } - if (cond4()) - return; // OK (outside c_auto) -} + // do the return/break outside of c_auto + if (flag < 0) return flag; + else if (flag > 0) break; + ... + } // for +``` + +### c_forarray, c_forarray_p +Iterate compound literal array elements +```c +// apply multiple push_backs +c_forarray (int, v, {1, 2, 3}) + cvec_i_push_back(&vec, *v); + +// insert in existing map +c_forarray (cmap_ii_raw, v, {{4, 5}, {6, 7}}) + cmap_ii_insert(&map, v->first, v->second); + +// even define an anonymous struct inside it (no commas allowed) +c_forarray (struct { int a; int b; }, v, {{1, 2}, {3, 4}, {5, 6}}) + printf("{%d %d} ", v->a, v->b); + +// `c_forarray_p` is required for pointer type elements +c_forarray_p (const char*, v, {"Hello", "crazy", "world"}) + cstack_s_push(&stk, *v); ``` ### c_foreach, c_forpair -| Usage | Description | -|:-------------------------------------------|:--------------------------------| -| `c_foreach (it, ctype, container)` | Iteratate all elements | -| `c_foreach (it, ctype, it1, it2)` | Iterate the range [it1, it2) | -| `c_forpair (key, value, ctype, container)` | Iterate with structured binding | +| Usage | Description | +|:-----------------------------------------|:--------------------------------| +| `c_foreach (it, ctype, container)` | Iteratate all elements | +| `c_foreach (it, ctype, it1, it2)` | Iterate the range [it1, it2) | +| `c_forpair (key, val, ctype, container)` | Iterate with structured binding | ```c #define i_key int @@ -129,8 +167,9 @@ for (int i = 0; i<n; ++i) { #define i_tag ii #include <stc/csmap.h> ... -c_apply(v, csmap_ii_insert(&map, c_pair(v)), csmap_ii_value, - { {23,1}, {3,2}, {7,3}, {5,4}, {12,5} }); +c_forarray (csmap_ii_value, v, {{23,1}, {3,2}, {7,3}, {5,4}, {12,5}}) + csmap_ii_insert(&map, v->first, v->second); + c_foreach (i, csmap_ii, map) printf(" %d", i.ref->first); // out: 3 5 7 12 23 @@ -167,35 +206,20 @@ c_forrange (int, i, 30, 0, -5) printf(" %d", i); // 30 25 20 15 10 5 ``` -### c_apply, c_apply_array, c_pair, c_find_if, c_find_it -**c_apply** applies an expression on a container with each of the elements in the given array: -```c -// apply multiple push_backs -c_apply(v, cvec_i_push_back(&vec, v), int, {1, 2, 3}); - -// inserts to existing map -c_apply(v, cmap_i_insert(&map, c_pair(v)), cmap_i_raw, { {4, 5}, {6, 7} }); - -int arr[] = {1, 2, 3}; -c_apply_array(v, cvec_i_push_back(&vec, v), int, arr, c_arraylen(arr)); -``` -**c_find_if**, **c_find_in** searches linearily in containers using a predicate +### c_find_if, c_find_in +Search linearily in containers using a predicate ``` // NOTE: it.ref is NULL if not found, not cvec_i_end(&vec).ref // This makes it easier to test. cvec_i_iter it; -// Search the the whole vec -c_find_if(cvec_i, vec, it, *it.ref == 2); +// Search vec for first value > 2: +c_find_if(cvec_i, vec, it, *it.ref > 2); if (it.ref) printf("%d\n", *it.ref); -// Search from iter's current position -c_find_from(cvec_i, vec, it, index == 2); // index is internal in find_if. -if (it.ref) printf("%d\n", *it.ref); // 3 - -// Search in the range +// Search within a range: c_find_in(csmap_str, it1, it2, it, cstr_contains(*it.ref, "hello")); -cmap_str_erase_at(&map, it); // assume found +if (it.ref) cmap_str_erase_at(&map, it); ``` ### c_new, c_alloc, c_alloc_n, c_drop, c_make diff --git a/docs/cdeq_api.md b/docs/cdeq_api.md index 1840468c..6826946c 100644 --- a/docs/cdeq_api.md +++ b/docs/cdeq_api.md @@ -110,7 +110,9 @@ int main() { printf(" %d", *i.ref); puts(""); - c_apply(v, cdeq_i_push_back(&q, *v), int, {1, 4, 5, 22, 33, 2}); + c_forarray (int, v, {1, 4, 5, 22, 33, 2}) + cdeq_i_push_back(&q, *v) + c_foreach (i, cdeq_i, q) printf(" %d", *i.ref); puts(""); diff --git a/docs/clist_api.md b/docs/clist_api.md index a3a59b7c..274c0f6f 100644 --- a/docs/clist_api.md +++ b/docs/clist_api.md @@ -152,7 +152,8 @@ Use of *erase_at()* and *erase_range()*: int main () { clist_i L = clist_i_init(); - c_apply(v, clist_i_push_back(&L, *v), int, {10, 20, 30, 40, 50}); + c_forarray (int, v, {10, 20, 30, 40, 50}) + clist_i_push_back(&L, *v); // 10 20 30 40 50 clist_i_iter it = clist_i_begin(&L); // ^ clist_i_next(&it); @@ -187,8 +188,8 @@ Splice `[30, 40]` from *L2* into *L1* before `3`: int main() { c_auto (clist_i, L1, L2) { - c_apply(v, clist_i_push_back(&L1, *v), int, {1, 2, 3, 4, 5}); - c_apply(v, clist_i_push_back(&L2, *v), int, {10, 20, 30, 40, 50}); + c_forarray (int, v, {1, 2, 3, 4, 5}) clist_i_push_back(&L1, *v); + c_forarray (int, v, {10, 20, 30, 40, 50}) clist_i_push_back(&L2, *v); clist_i_iter i = clist_i_advance(clist_i_begin(&L1), 2); clist_i_iter j1 = clist_i_advance(clist_i_begin(&L2), 2), j2 = clist_i_advance(j1, 2); diff --git a/docs/cmap_api.md b/docs/cmap_api.md index 89d7f408..8fbfb30b 100644 --- a/docs/cmap_api.md +++ b/docs/cmap_api.md @@ -126,11 +126,11 @@ int main() // Create an unordered_map of three strings (that map to strings) c_auto (cmap_str, u) { - c_apply(v, cmap_str_emplace(&u, c_pair(v)), cmap_str_raw, { + c_forarray (cmap_str_raw, v, { {"RED", "#FF0000"}, {"GREEN", "#00FF00"}, {"BLUE", "#0000FF"} - }); + }) cmap_str_emplace(&u, v->first, v->second); // Iterate and print keys and values of unordered map c_foreach (n, cmap_str, u) { @@ -172,9 +172,9 @@ int main() c_auto (cmap_id, idnames) { - c_apply(v, cmap_id_emplace(&idnames, c_pair(v)), cmap_id_raw, { - {100, "Red"}, {110, "Blue"} - }); + c_forarray (cmap_id_raw, v, {{100, "Red"}, {110, "Blue"}}) + cmap_id_emplace(&idnames, v->first, v->second); + // replace existing mapped value: cmap_id_emplace_or_assign(&idnames, 110, "White"); diff --git a/docs/cset_api.md b/docs/cset_api.md index 95a236b1..2d3ab6e7 100644 --- a/docs/cset_api.md +++ b/docs/cset_api.md @@ -86,10 +86,11 @@ int main () c_auto (cset_str, first, second) c_auto (cset_str, third, fourth) { - c_apply(v, cset_str_emplace(&second, *v), const char*, - {"red", "green", "blue"}); - c_apply(v, cset_str_emplace(&third, *v), const char*, - {"orange", "pink", "yellow"}); + c_forarray_p (const char*, v, {"red", "green", "blue"}) + cset_str_emplace(&second, *v); + + c_forarray_p (const char*, v, {"orange", "pink", "yellow"}) + cset_str_emplace(&third, *v); cset_str_emplace(&fourth, "potatoes"); cset_str_emplace(&fourth, "milk"); @@ -98,6 +99,7 @@ int main () fifth = cset_str_clone(second); c_foreach (i, cset_str, third) cset_str_emplace(&fifth, cstr_str(i.ref)); + c_foreach (i, cset_str, fourth) cset_str_emplace(&fifth, cstr_str(i.ref)); } diff --git a/docs/csmap_api.md b/docs/csmap_api.md index 01b77cb4..c3e3f3ea 100644 --- a/docs/csmap_api.md +++ b/docs/csmap_api.md @@ -113,11 +113,11 @@ int main() // Create a sorted map of three strings (maps to string) c_auto (csmap_str, colors) // RAII { - c_apply(v, csmap_str_emplace(&colors, c_pair(v)), csmap_str_raw, { + c_forarray (csmap_str_raw, v, { {"RED", "#FF0000"}, {"GREEN", "#00FF00"}, {"BLUE", "#0000FF"} - }); + }) csmap_str_emplace(&colors, v->first, v->second); // Iterate and print keys and values of sorted map c_foreach (i, csmap_str, colors) { @@ -159,14 +159,15 @@ int main() csmap_id idnames = csmap_id_init(); c_autodefer (csmap_id_drop(&idnames)) { - c_apply(v, csmap_id_emplace(&idnames, c_pair(v)), csmap_id_raw, { - {100, "Red"}, - {110, "Blue"}, - }); + c_forarray (csmap_id_raw, v, {{100, "Red"}, {110, "Blue"}}) + csmap_id_emplace(&idnames, v->first, v->second); + // put replaces existing mapped value: csmap_id_emplace_or_assign(&idnames, 110, "White"); + // put a constructed mapped value into map: csmap_id_insert_or_assign(&idnames, 120, cstr_from_fmt("#%08x", col)); + // emplace adds only when key does not exist: csmap_id_emplace(&idnames, 100, "Green"); diff --git a/docs/csset_api.md b/docs/csset_api.md index 30e57ca4..f2667376 100644 --- a/docs/csset_api.md +++ b/docs/csset_api.md @@ -85,10 +85,11 @@ c_auto (csset_str, fifth) c_auto (csset_str, first, second) c_auto (csset_str, third, fourth) { - c_apply(v, csset_str_emplace(&second, *v), const char*, - {"red", "green", "blue"}); - c_apply(v, csset_str_emplace(&third, *v), const char*, - {"orange", "pink", "yellow"}); + c_forarray_p (const char*, v, {"red", "green", "blue"}) + csset_str_emplace(&second, *v); + + c_forarray_p (const char*, v, {"orange", "pink", "yellow"}) + csset_str_emplace(&third, *v); csset_str_emplace(&fourth, "potatoes"); csset_str_emplace(&fourth, "milk"); diff --git a/docs/cvec_api.md b/docs/cvec_api.md index db2bd8ce..a907c827 100644 --- a/docs/cvec_api.md +++ b/docs/cvec_api.md @@ -123,7 +123,8 @@ int main() cvec_int_push(&vec, 13); // Append a set of numbers - c_apply(v, cvec_int_push(&vec, *v), int, {7, 5, 16, 8}); + c_forarray (int, v, {7, 5, 16, 8}) + cvec_int_push(&vec, *v); printf("initial:"); c_foreach (k, cvec_int, vec) { |
