diff options
| author | Tyge Løvset <[email protected]> | 2023-02-13 23:01:15 +0100 |
|---|---|---|
| committer | Tyge Løvset <[email protected]> | 2023-02-13 23:01:15 +0100 |
| commit | c849c2c058bfd8b66ecbd741e49c471773d66dd6 (patch) | |
| tree | 9870dee078b271b198c1fa998fa050295aee04d7 | |
| parent | 98f126a304f296dea2517d9e81c7f8e7b3aa80f5 (diff) | |
| download | STC-modified-c849c2c058bfd8b66ecbd741e49c471773d66dd6.tar.gz STC-modified-c849c2c058bfd8b66ecbd741e49c471773d66dd6.zip | |
Improved docs.
| -rw-r--r-- | README.md | 10 | ||||
| -rw-r--r-- | docs/ccommon_api.md | 124 | ||||
| -rw-r--r-- | docs/cspan_api.md | 18 |
3 files changed, 77 insertions, 75 deletions
@@ -12,9 +12,9 @@ I am happy to finally announce a new release! Major changes: - Updates on **cregex** with several [new unicode character classes](docs/cregex_api.md#regex-cheatsheet). - Algorithms: - [crange](docs/ccommon_api.md#crange) - similar to [boost::irange](https://www.boost.org/doc/libs/release/libs/range/doc/html/range/reference/ranges/irange.html) integer range generator. - - [c_forfilter](docs/ccommon_api.md#c_forfilter) - ranges-like filtering. + - [c_forfilter](docs/ccommon_api.md#c_forfilter) - ranges-like view filtering. - [csort](misc/benchmarks/various/csort_bench.c) - fast quicksort with custom inline comparison. -- Renamed `c_ARGSV()` => `c_SV()`: **csview** print arg. `c_sv()` is the shorthand **csview** constructor. +- Renamed `c_ARGSV()` => `c_SV()`: **csview** print arg. `c_sv()` is a shorthand for *csview_from()* constructor. - Support for [uppercase flow-control](include/stc/priv/altnames.h) macro names in ccommon.h. - Some API changes in **cregex** and **cstr**. - Create single header container versions with python script. @@ -133,9 +133,9 @@ for lookup in containers. E.g. for containers with string type (**cstr**) elemen as lookup type. It will then use the input `const char*` directly when comparing with the string data in the container. This avoids the construction of a new `cstr` (which possible allocates memory) for the lookup. Finally, destruction of the lookup key (i.e. string literal) after usage is not needed (or allowed), which -is convenient in C. A great ergonomic feature is that the alternative lookup type can also be used for adding +is convenient in C. A great ergonomic feature is that the alternative lookup type can also be used when adding entries into containers through using the *emplace*-functions. E.g. `cvec_str_emplace_back(&vec, "Hello")`. -3. ***Standardized container iterators***. All container can be iterated the same way, and uses the +3. ***Standardized container iterators***. All container can be iterated in similar manner, and uses the same element access syntax. E.g.: - `c_foreach (it, IntContainer, container) printf(" %d", *it.ref);` will work for every type of container defined as `IntContainer` with `int` elements. Also the form: @@ -394,7 +394,7 @@ Val: - `i_valfrom` *Func* - Convertion func *i_val* <= *i_valraw*. - `i_valto` *Func* - Convertion func *i_val*\* => *i_valraw*. -Specials: Meta-template parameters (use instead of `i_key` / `i_val`): +Specials: Meta-template parameters. Use instead of `i_key` / `i_val`. - `i_keyclass` *Type* - Auto-set standard named functions: *Type_clone()*, *Type_drop()*, *Type_cmp()*, *Type_eq()*, *Type_hash()*. If `i_keyraw` is defined, it sets `i_keyto` = *Type_toraw()* and `i_keyfrom` = *Type_from()*. Only functions required by the container type is required to be defined. E.g.: diff --git a/docs/ccommon_api.md b/docs/ccommon_api.md index 20517630..60167c06 100644 --- a/docs/ccommon_api.md +++ b/docs/ccommon_api.md @@ -32,7 +32,7 @@ c_with (FILE* fp = fopen(fname, "rb"), fp != NULL, fclose(fp)) } return ok; -// `c_auto` automatically initialize and destruct up to 4 variables, like c_with. +// `c_auto` automatically initialize and destruct up to 4 variables: c_auto (cstr, s1, s2) { cstr_append(&s1, "Hello"); @@ -44,6 +44,7 @@ c_auto (cstr, s1, s2) printf("%s %s\n", cstr_str(&s1), cstr_str(&s2)); } +// `c_with` is a general variant of `c_auto`: c_with (cstr str = cstr_lit("Hello"), cstr_drop(&str)) { cstr_append(&str, " world"); @@ -91,55 +92,6 @@ int main() printf("%s\n", cstr_str(i.ref)); } ``` - -### The **checkauto** utility program (for RAII) -The **checkauto** program will check the source code for any misuses of the `c_auto*` macros which -may lead to resource leakages. The `c_auto*`- macros are implemented as one-time executed **for-loops**, -so any `return` or `break` appearing within such a block will lead to resource leaks, as it will disable -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: 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 - 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; // 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 - } - ... - } - // do the return/break outside of c_auto - if (flag < 0) return flag; - else if (flag > 0) break; - ... - } // for -``` ## Loop abstraction macros ### c_forlist @@ -244,26 +196,27 @@ Iterate containers with stop-criteria and chained range filtering. #include <stdio.h> bool isPrime(int i) { - for (int j=2; j*j <= i; ++j) if (i % j == 0) return false; + for (int j=2; j*j <= i; ++j) + if (i % j == 0) return false; return true; } -// Get 10 prime numbers after 1 million, but only every 25th of them. - int main() { - crange R = crange_make(1000001, INT32_MAX, 2); + // Get 10 prime numbers starting from 1000. + // Skip the first 24 primes, then select every 15th prime. + crange R = crange_make(1001, INT32_MAX, 2); c_forfilter (i, crange, R, isPrime(*i.ref) - && c_flt_count(i) % 25 == 0 - , c_flt_take(i, 10)) // breaks loop on false. - { + && c_flt_skip(i, 24) + && c_flt_count(i) % 15 == 1 + , c_flt_take(i, 10)) // , = breaks loop on false. printf(" %d", *i.ref); - } + puts(""); } -// Out: 1000303 1000639 1000999 1001311 1001593 1001981 1002299 1002583 1002887 1003241 +// out: 1171 1283 1409 1493 1607 1721 1847 1973 2081 2203 ``` -Note that `c_flt_take()` is given as an optional argument, which breaks the loop on false -(for efficiency). Without the comma, it will give same result, but the full input is processed first. +Note that `c_flt_take()` is given as an optional argument, which breaks the loop on false. +With `&&` instead of the comma it will give same result, but the full input is processed first. ### c_make, c_new, c_delete @@ -368,3 +321,52 @@ Return number of elements in an array. array must not be a pointer! int array[] = {1, 2, 3, 4}; intptr_t n = c_arraylen(array); ``` + +## 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. A `break` may originally be intended to break a loop or switch +outside the `c_auto` scope. + +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 +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; // 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 + } + ... + } + // do the return/break outside of c_auto + if (flag < 0) return flag; + else if (flag > 0) break; + ... +} +``` diff --git a/docs/cspan_api.md b/docs/cspan_api.md index 1bd36446..1e60a526 100644 --- a/docs/cspan_api.md +++ b/docs/cspan_api.md @@ -1,9 +1,9 @@ # STC [cspan](../include/stc/cspan.h): Multi-dimensional Array View  -The **cspan** is templated non-owning *single* and *multi-dimensional* view of an array. It is similar -to Python's numpy array slicing and C++ [std::span](https://en.cppreference.com/w/cpp/container/span) / -[std::mdspan](https://en.cppreference.com/w/cpp/container/mdspan). +The **cspan** is templated non-owning *single* and *multi-dimensional* view of an array. It has similarities +with Python's numpy array slicing and C++ [std::span](https://en.cppreference.com/w/cpp/container/span) / +[std::mdspan](https://en.cppreference.com/w/cpp/container/mdspan), and others. ## Header file and declaration **cspan** types are defined by the *using_cspan()* macro after the header is included. @@ -68,7 +68,7 @@ void SpanType_next(SpanTypeN_iter* it); ## Example 1 -The *cspan_slice()* function is similar to pythons numpy multi-dimensional arrays slicing, e.g.: +Dimension slicing in python, C, and C++: ```py import numpy as np @@ -92,7 +92,7 @@ if __name__ == '__main__': ``` ... can be written in C using cspan: ```c -#include <c11/fmt.h> +#include <stdio.h> #include <stc/cspan.h> using_cspan3(myspan, int); // define myspan, myspan2, myspan3. @@ -105,11 +105,11 @@ int main() { c_forrange (i, ss2.shape[0]) c_forrange (j, ss2.shape[1]) - fmt_print(" {}", *cspan_at(&ss2, i, j)); + printf(" %d", *cspan_at(&ss2, i, j)); puts(""); c_foreach (i, myspan2, ss2) - fmt_print(" {}", *i.ref); + printf(" %d", *i.ref); } ``` ... and (almost) in C++23: @@ -130,11 +130,11 @@ int main() { std::print(" {}", ss2[i, j]); std::println(); - // std::mdspan can't be iterated as a flat container! + // std::mdspan can't be iterated joined/flat! } ``` ## Example 2 -Slicing cspan without and with reducing the rank (like numpy array slicing): +Slicing cspan without and with reducing the rank: ```c #include <c11/fmt.h> #include <stc/cspan.h> |
