summaryrefslogtreecommitdiffhomepage
path: root/docs
diff options
context:
space:
mode:
authorTyge Løvset <[email protected]>2022-08-06 17:48:06 +0200
committerTyge Løvset <[email protected]>2022-08-06 17:48:06 +0200
commit618b5704e6f85cfe1b6e5c9c9373abe76a8bb628 (patch)
tree4e25a538c8ba3fd58bb25b90ff6dc54adfb31aa4 /docs
parent927fa8093ea0bc1e25586e60c47cf1dd8a311d9e (diff)
downloadSTC-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.md15
-rw-r--r--docs/cbox_api.md4
-rw-r--r--docs/ccommon_api.md122
-rw-r--r--docs/cdeq_api.md4
-rw-r--r--docs/clist_api.md7
-rw-r--r--docs/cmap_api.md10
-rw-r--r--docs/cset_api.md10
-rw-r--r--docs/csmap_api.md13
-rw-r--r--docs/csset_api.md9
-rw-r--r--docs/cvec_api.md3
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) {