diff options
| author | Tyge Løvset <[email protected]> | 2023-02-14 07:54:01 +0100 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-02-14 07:54:01 +0100 |
| commit | e456085a392d063df1a2495422523a2474ea6a18 (patch) | |
| tree | 363250af394400d0fb6a33763f5a89acd1b4dd61 /docs | |
| parent | 7dc6fddc079f4f572c8fb7c0ffd5a27e03291a2d (diff) | |
| parent | 6df7f90dbabf7f60e37109335f2cb8f8b6b5d02f (diff) | |
| download | STC-modified-e456085a392d063df1a2495422523a2474ea6a18.tar.gz STC-modified-e456085a392d063df1a2495422523a2474ea6a18.zip | |
Merge pull request #48 from tylov/dev411
Release V4.1.1
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/cbits_api.md | 40 | ||||
| -rw-r--r-- | docs/ccommon_api.md | 133 | ||||
| -rw-r--r-- | docs/cregex_api.md | 8 | ||||
| -rw-r--r-- | docs/cspan_api.md | 18 | ||||
| -rw-r--r-- | docs/csview_api.md | 28 |
5 files changed, 114 insertions, 113 deletions
diff --git a/docs/cbits_api.md b/docs/cbits_api.md index 60586a5b..21c9a86d 100644 --- a/docs/cbits_api.md +++ b/docs/cbits_api.md @@ -21,34 +21,34 @@ All cbits definitions and prototypes are available by including a single header ```c cbits cbits_init(void); cbits cbits_from(const char* str); -cbits cbits_with_size(intptr_t size, bool value); // size must be <= N if N is defined -cbits cbits_with_pattern(intptr_t size, uint64_t pattern); +cbits cbits_with_size(int64_t size, bool value); // size must be <= N if N is defined +cbits cbits_with_pattern(int64_t size, uint64_t pattern); cbits cbits_clone(cbits other); void cbits_clear(cbits* self); cbits* cbits_copy(cbits* self, const cbits* other); -void cbits_resize(cbits* self, intptr_t size, bool value); // only if i_len is not defined +void cbits_resize(cbits* self, int64_t size, bool value); // only if i_len is not defined void cbits_drop(cbits* self); cbits* cbits_take(cbits* self, const cbits* other); // give other to self cbits cbits_move(cbits* self); // transfer self to caller -intptr_t cbits_size(const cbits* self); -intptr_t cbits_count(const cbits* self); // count number of bits set +int64_t cbits_size(const cbits* self); +int64_t cbits_count(const cbits* self); // count number of bits set -bool cbits_test(const cbits* self, intptr_t i); -bool cbits_at(const cbits* self, intptr_t i); // same as cbits_test() +bool cbits_test(const cbits* self, int64_t i); +bool cbits_at(const cbits* self, int64_t i); // same as cbits_test() bool cbits_subset_of(const cbits* self, const cbits* other); // is set a subset of other? bool cbits_disjoint(const cbits* self, const cbits* other); // no common bits -char* cbits_to_str(const cbits* self, char* str, intptr_t start, intptr_t stop); +char* cbits_to_str(const cbits* self, char* str, int64_t start, int64_t stop); -void cbits_set(cbits* self, intptr_t i); -void cbits_reset(cbits* self, intptr_t i); -void cbits_set_value(cbits* self, intptr_t i, bool value); +void cbits_set(cbits* self, int64_t i); +void cbits_reset(cbits* self, int64_t i); +void cbits_set_value(cbits* self, int64_t i, bool value); void cbits_set_all(cbits* self, bool value); void cbits_set_pattern(cbits* self, uint64_t pattern); void cbits_flip_all(cbits* self); -void cbits_flip(cbits* self, intptr_t i); +void cbits_flip(cbits* self, int64_t i); void cbits_intersect(cbits* self, const cbits* other); void cbits_union(cbits* self, const cbits* other); @@ -70,19 +70,19 @@ void cbits_xor(cbits* self, const cbits* other); // set of di #include <math.h> #include <time.h> -cbits sieveOfEratosthenes(intptr_t n) +cbits sieveOfEratosthenes(int64_t n) { cbits bits = cbits_with_size(n>>1, true); - intptr_t q = (intptr_t) sqrt(n); + int64_t q = (int64_t) sqrt(n); - for (intptr_t i = 3; i <= q; i += 2) { - for (intptr_t j = i; j < n; j += 2) { + for (int64_t i = 3; i <= q; i += 2) { + for (int64_t j = i; j < n; j += 2) { if (cbits_test(&bits, j>>1)) { i = j; break; } } - for (intptr_t j = i*i; j < n; j += i*2) + for (int64_t j = i*i; j < n; j += i*2) cbits_reset(&bits, j>>1); } return bits; @@ -90,18 +90,18 @@ cbits sieveOfEratosthenes(intptr_t n) int main(void) { - intptr_t n = 100000000; + int64_t n = 100000000; printf("computing prime numbers up to %" c_ZI "\n", n); clock_t t1 = clock(); cbits primes = sieveOfEratosthenes(n + 1); - intptr_t nprimes = cbits_count(&primes); + int64_t nprimes = cbits_count(&primes); clock_t t2 = clock(); printf("number of primes: %" c_ZI ", time: %f\n", nprimes, (float)(t2 - t1)/CLOCKS_PER_SEC); printf(" 2"); - for (intptr_t i = 3; i < 1000; i += 2) + for (int64_t i = 3; i < 1000; i += 2) if (cbits_test(&primes, i>>1)) printf(" %" c_ZI, i); puts(""); diff --git a/docs/ccommon_api.md b/docs/ccommon_api.md index a2f0b99d..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 @@ -229,12 +181,12 @@ Iterate containers with stop-criteria and chained range filtering. | Built-in filter | Description | |:----------------------------------|:-------------------------------------| -| `c_flt_skip(it, numItems)` | Skip numItems | -| `c_flt_take(it, numItems)` | Take numItems | +| `c_flt_skip(it, numItems)` | Skip numItems (inc count) | +| `c_flt_take(it, numItems)` | Take numItems (inc count) | | `c_flt_skipwhile(it, predicate)` | Skip items until predicate is false | | `c_flt_takewhile(it, predicate)` | Take items until predicate is false | -| `c_flt_last(it)` | Get count of last filter successes | -| `c_flt_lastwhile(it)` | Get value of last while-filter | +| `c_flt_count(it)` | Increment current and return value | +| `c_flt_last(it)` | Get value of last count/skip/take | `it.index` holds the index of the source item. ```c @@ -244,27 +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_skip(i, INT32_MAX) || - c_flt_last(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 @@ -369,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/cregex_api.md b/docs/cregex_api.md index 8cabb6fc..64fb6a2b 100644 --- a/docs/cregex_api.md +++ b/docs/cregex_api.md @@ -108,7 +108,7 @@ int main() { // Lets find the first date in the string: csview match[4]; // full-match, year, month, date. if (cregex_find(&re, input, match, CREG_DEFAULT) == CREG_OK) - printf("Found date: %.*s\n", c_SVARG(match[0])); + printf("Found date: %.*s\n", c_SV(match[0])); else printf("Could not find any date\n"); @@ -124,7 +124,7 @@ int main() { For a single match you may use the all-in-one function: ```c if (cregex_find_pattern(pattern, input, match, CREG_DEFAULT)) - printf("Found date: %.*s\n", c_SVARG(match[0])); + printf("Found date: %.*s\n", c_SV(match[0])); ``` To compile, use: `gcc first_match.c src/cregex.c src/utf8code.c`. @@ -137,13 +137,13 @@ To iterate multiple matches in an input string, you may use csview match[5] = {0}; while (cregex_find(&re, input, match, CREG_M_NEXT) == CREG_OK) c_forrange (k, cregex_captures(&re)) - printf("submatch %lld: %.*s\n", k, c_SVARG(match[k])); + printf("submatch %lld: %.*s\n", k, c_SV(match[k])); ``` There is also a safe macro which simplifies this: ```c c_formatch (it, &re, input) c_forrange (k, cregex_captures(&re)) - printf("submatch %lld: %.*s\n", k, c_SVARG(it.match[k])); + printf("submatch %lld: %.*s\n", k, c_SV(it.match[k])); ``` ## Using cregex in a project 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> diff --git a/docs/csview_api.md b/docs/csview_api.md index 29c59d9c..33e61f0e 100644 --- a/docs/csview_api.md +++ b/docs/csview_api.md @@ -26,11 +26,11 @@ All csview definitions and prototypes are available by including a single header ## Methods ```c -csview c_SV(const char literal_only[]); // construct from literal, no strlen() -csview c_SV(const char* str, intptr_t n); // construct from str and length n -csview csview_lit(const char literal_only[]); // alias for c_SV(lit) +csview c_sv(const char literal_only[]); // construct from literal, no strlen() +csview c_sv(const char* str, intptr_t n); // construct from str and length n +csview csview_lit(const char literal_only[]); // alias for c_sv(lit) csview csview_from(const char* str); // construct from const char* -csview csview_from_n(const char* str, intptr_t n); // alias for c_SV(str, n) +csview csview_from_n(const char* str, intptr_t n); // alias for c_sv(str, n) intptr_t csview_size(csview sv); bool csview_empty(csview sv); @@ -88,7 +88,7 @@ csview cstr_slice_ex(const cstr* s, intptr_t p, intptr_t q); // nega To iterate tokens in an input string separated by a string: ```c c_fortoken (i, "hello, one, two, three", ", ") - printf("token: %.*s\n", c_SVARG(i.token)); + printf("token: %.*s\n", c_SV(i.token)); ``` #### Helper methods @@ -111,8 +111,8 @@ uint64_t csview_hash(const csview* x); | Name | Value | Usage | |:---------------|:---------------------|:---------------------------------------------| -| `csview_NULL` | same as `c_SV("")` | `sview = csview_NULL;` | -| `c_SVARG(sv)` | printf argument | `printf("sv: %.*s\n", c_SVARG(sv));` | +| `csview_NULL` | same as `c_sv("")` | `sview = csview_NULL;` | +| `c_SV(sv)` | printf argument | `printf("sv: %.*s\n", c_SV(sv));` | ## Example ```c @@ -129,7 +129,7 @@ int main () csview sv2 = cstr_substr(&str1, pos, 4); // get "live" csview sv3 = cstr_slice(&str1, -8, -1); // get "details" printf("%.*s %.*s %.*s\n", - c_SVARG(sv1), c_SVARG(sv2), c_SVARG(sv3)); + c_SV(sv1), c_SV(sv2), c_SV(sv3)); cstr s1 = cstr_lit("Apples are red"); cstr s2 = cstr_from_sv(cstr_substr(&s1, -3, 3)); // "red" cstr s3 = cstr_from_sv(cstr_substr(&s1, 0, 6)); // "Apples" @@ -153,11 +153,11 @@ int main() { c_auto (cstr, s1) { s1 = cstr_lit("hell😀 w😀rld"); - cstr_u8_replace_at(&s1, cstr_find(&s1, "😀rld"), 1, c_SV("ø")); + cstr_u8_replace_at(&s1, cstr_find(&s1, "😀rld"), 1, c_sv("ø")); printf("%s\n", cstr_str(&s1)); c_foreach (i, cstr, s1) - printf("%.*s,", c_SVARG(i.u8.chr)); + printf("%.*s,", c_SV(i.u8.chr)); } } ``` @@ -177,7 +177,7 @@ and does not depend on null-terminated strings. *string_split()* function return void print_split(csview input, const char* sep) { c_fortoken_sv (i, input, sep) - printf("[%.*s]\n", c_SVARG(i.token)); + printf("[%.*s]\n", c_SV(i.token)); } #include <stc/cstr.h> @@ -196,12 +196,12 @@ cstack_str string_split(csview input, const char* sep) int main() { - print_split(c_SV("//This is a//double-slash//separated//string"), "//"); + print_split(c_sv("//This is a//double-slash//separated//string"), "//"); puts(""); - print_split(c_SV("This has no matching separator"), "xx"); + print_split(c_sv("This has no matching separator"), "xx"); puts(""); - c_with (cstack_str s = string_split(c_SV("Split,this,,string,now,"), ","), cstack_str_drop(&s)) + c_with (cstack_str s = string_split(c_sv("Split,this,,string,now,"), ","), cstack_str_drop(&s)) c_foreach (i, cstack_str, s) printf("[%s]\n", cstr_str(i.ref)); } |
