diff options
| author | Tyge Løvset <[email protected]> | 2022-01-12 10:55:35 +0100 |
|---|---|---|
| committer | Tyge Løvset <[email protected]> | 2022-01-12 10:55:35 +0100 |
| commit | d616e7db3a2325646e8647cdc433b12e9438c251 (patch) | |
| tree | 69cbc1d259ba7ca01c01ef20e0179c1e59fdfaf1 | |
| parent | f69fb08603aca020e8d855b0469809982bb67322 (diff) | |
| download | STC-modified-d616e7db3a2325646e8647cdc433b12e9438c251.tar.gz STC-modified-d616e7db3a2325646e8647cdc433b12e9438c251.zip | |
Docs update, mmap.c example update.
| -rw-r--r-- | README.md | 49 | ||||
| -rw-r--r-- | docs/ccommon_api.md | 32 | ||||
| -rw-r--r-- | examples/mmap.c | 35 |
3 files changed, 63 insertions, 53 deletions
@@ -3,32 +3,13 @@ STC - Smart Template Containers for C ===================================== -News ----- -## Version 3 released +News: Version 3 released (Jan 2022) +----------------------------------- This version introduces lots of enhancements, bugfixes and additions. There are also -a number of breaking changes, see below for changes and [a migration guide from version 2 to 3](#migration-guide-from-version-2-to-3). +a number of [breaking changes](#brief-summary-of-changes) and [a migration guide from version 2 to 3](#migration-guide-from-version-2-to-3). With version 3, the API is freezed as far as possible. Any changes will be handled with long lasting deprecations, so you may develop production code using it. -### Brief summary of changes -- Renamed: all ***_del*** to `_drop` (like destructors in Rust). -- Renamed: all ***_compare*** to `_cmp` -- Renamed: ***i_equ*** to `i_eq`, and ***_equalto*** to `_eq`. -- Renamed: ***i_cnt*** to `i_type` for defining the complete container type name. -- Renamed: type **csptr** to [**carc**](docs/carc_api.md) (atomic reference counted) smart pointer. -- Renamed: ***i_key_csptr*** / ***i_val_csptr*** to `i_key_sptr` / `i_val_sptr` for specifying **carc** and **cbox** values in containers. -- Renamed: *csptr_X_make()* to `carc_X_from()`. -- Renamed: *cstr_lit()* to `cstr_new(literal)`, and *cstr_assign_fmt()* to `cstr_printf()`. -- Renamed: *c_default_fromraw()* to `c_default_from()`. -- Changed: the [**c_apply**](docs/ccommon_api.md) macros API. -- Replaced: *csview_first_token()* and *csview_next_token()* with one function: `csview_token()`. -- Added: **checkauto** tool for checking that c-source files uses `c_auto*` macros correctly. -- Added: general `i_key_bind` / `i_val_bind` template parameters which auto-binds template functions. -- Added: `i_opt` template parameter: compile-time options: `c_no_cmp`, `c_no_clone`, `c_no_atomic`, `c_is_fwd`; may be combined with `|` -- Added: [**cbox**](docs/cbox_api.md) type: smart pointer, similar to [Rust Box](https://doc.rust-lang.org/rust-by-example/std/box.html) and [std::unique_ptr](https://en.cppreference.com/w/cpp/memory/unique_ptr). -- Added: [**c_forpair**](docs/ccommon_api.md) macro: for-loop with "structured binding" - Introduction ------------ STC is a modern, templated, user-friendly, fast, fully type-safe, and customizable container library for C99, @@ -43,6 +24,7 @@ For an introduction to templated containers, please read the blog by Ian Fisher Note that STC does not use long macro expansions anymore, but relies on one or more inclusions of the same file, which by the compiler is seen as different code because of macro name substitutions. +- [***ccommon*** - RAII and iterator macros](docs/ccommon_api.md) - [***carr2, carr3*** - **2d** and **3d** dynamic **array** type](docs/carray_api.md) - [***cbits*** - **std::bitset** alike type](docs/cbits_api.md) - [***cbox*** - **std::unique_ptr** alike type](docs/cbox_api.md) @@ -61,7 +43,7 @@ which by the compiler is seen as different code because of macro name substituti - [***cvec*** - **std::vector** alike type](docs/cvec_api.md) Others: -- [***ccommon*** - Some handy macros and general definitions](docs/ccommon_api.md) +- [***threads*** - Mimic **C11-threads** (by Marcus Geelnard)](include/threads.h) - [***crandom*** - A novel very fast *PRNG* named **stc64**](docs/crandom_api.md) - [***coption*** - Command line options scanner](docs/coption_api.md) @@ -444,8 +426,27 @@ Memory efficiency - **carr2**, **carr3**: Type size: 1 pointer plus dimension variables. Arrays are allocated as one contiguous block of heap memory, and one allocation for pointers of indices to the array. - **carc**: Type size: 2 pointers, one for the data and one for the reference counter. +# Version 3 + +## Brief summary of changes +- Renamed: all ***_del*** to `_drop` (like destructors in Rust). +- Renamed: all ***_compare*** to `_cmp` +- Renamed: ***i_equ*** to `i_eq`, and ***_equalto*** to `_eq`. +- Renamed: ***i_cnt*** to `i_type` for defining the complete container type name. +- Renamed: type **csptr** to [**carc**](docs/carc_api.md) (atomic reference counted) smart pointer. +- Renamed: ***i_key_csptr*** / ***i_val_csptr*** to `i_key_sptr` / `i_val_sptr` for specifying **carc** and **cbox** values in containers. +- Renamed: *csptr_X_make()* to `carc_X_from()`. +- Renamed: *cstr_lit()* to `cstr_new(literal)`, and *cstr_assign_fmt()* to `cstr_printf()`. +- Renamed: *c_default_fromraw()* to `c_default_from()`. +- Changed: the [**c_apply**](docs/ccommon_api.md) macros API. +- Replaced: *csview_first_token()* and *csview_next_token()* with one function: `csview_token()`. +- Added: **checkauto** tool for checking that c-source files uses `c_auto*` macros correctly. +- Added: general `i_key_bind` / `i_val_bind` template parameters which auto-binds template functions. +- Added: `i_opt` template parameter: compile-time options: `c_no_cmp`, `c_no_clone`, `c_no_atomic`, `c_is_fwd`; may be combined with `|` +- Added: [**cbox**](docs/cbox_api.md) type: smart pointer, similar to [Rust Box](https://doc.rust-lang.org/rust-by-example/std/box.html) and [std::unique_ptr](https://en.cppreference.com/w/cpp/memory/unique_ptr). +- Added: [**c_forpair**](docs/ccommon_api.md) macro: for-loop with "structured binding" -# Migration guide from version 2 to 3 +## Migration guide from version 2 to 3 Replace (regular expression) globally in code base (VS Code): - `_del\b` ⟶ `_drop` - `_compare\b` ⟶ `_cmp` diff --git a/docs/ccommon_api.md b/docs/ccommon_api.md index 46e25737..db9ef911 100644 --- a/docs/ccommon_api.md +++ b/docs/ccommon_api.md @@ -1,10 +1,11 @@ -# STC [ccommon](../include/stc/ccommon.h): Common definitions and handy macros +# STC [ccommon](../include/stc/ccommon.h): RAII and iterator macros -The following handy macros are safe to use, i.e. have no side-effects. +The following macros are recommended to use, and they safe/have no side-effects. ### c_auto, c_autovar, c_autoscope, c_autodefer -General ***defer*** mechanics for resource acquisition. These macros allows to specify the release of the -resource where the resource acquisition takes place. Makes it easier to verify that resources are released. +General ***defer*** mechanics for resource acquisition. These macros allows you to specify the +freeing of the resources at the point where the acquisition takes place. +The **checkauto** utility described below, ensures that the `c_auto*` macros are used correctly. | Usage | Description | |:---------------------------------------|:-----------------------------------------------------| @@ -17,13 +18,14 @@ resource where the resource acquisition takes place. Makes it easier to verify t 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. ```c -c_autovar (uint8_t* buf = c_alloc_n(uint8_t, N), c_free(buf)) +c_autovar (uint8_t* buf = malloc(BUF_SIZE), free(buf)) c_autovar (FILE* f = fopen(fname, "rb"), fclose(f)) { int n = 0; - if (f && buf) - n = fread(buf, 1, N, f); - if (n > 0) doSomething(buf, n); + if (f && buf) { + n = fread(buf, 1, BUF_SIZE, f); + doSomething(buf, n); + } } c_autovar (cstr s = cstr_new("Hello"), cstr_drop(&s)) @@ -69,9 +71,9 @@ cvec_str readFile(const char* name) cvec_str vec = cvec_str_init(); // returned c_autovar (FILE* fp = fopen(name, "r"), fclose(fp)) - c_autovar (cstr line = cstr_null, cstr_drop(&line)) - while (cstr_getline(&line, fp)) - cvec_str_emplace_back(&vec, line.str); + c_autovar (cstr line = cstr_null, cstr_drop(&line)) + while (cstr_getline(&line, fp)) + cvec_str_emplace_back(&vec, line.str); return vec; } @@ -86,7 +88,7 @@ int main() 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 an immediate +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. @@ -94,19 +96,19 @@ with `break`, then use `c_breakauto` to break out of the `c_auto` scope(s). Afte 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, - it is much easier to automatically detect misplaced return/break between resource acquisition and destruction. -- it prevent forgetting to call the destructor at the end. +- it prevents forgetting to call the destructor at the end. ```c for (int i = 0; i<n; ++i) { c_auto (List, list) { List_push_back(&list, i); if (cond1()) - break; // checkauto Error + break; // checkauto: Error for (j = 0; j<m; ++j) { if (cond2()) break; // OK (breaks for-loop only) } if (cond3()) - return; // checkauto Error + return; // checkauto: Error } if (cond4()) return; // OK (outside c_auto) diff --git a/examples/mmap.c b/examples/mmap.c index ea08017b..289da616 100644 --- a/examples/mmap.c +++ b/examples/mmap.c @@ -1,18 +1,20 @@ // This implements the multimap c++ example found at:
// https://en.cppreference.com/w/cpp/container/multimap/insert
-// Map of int => clist_str. Note the negation of c_default_cmp
+// Multimap entries
#define i_val_str
#include <stc/clist.h>
+// Map of int => clist_str.
#define i_type Multimap
#define i_key int
-#define i_val_bind clist_str
-#define i_cmp -c_default_cmp
+#define i_val_bind clist_str // uses clist_str as i_val and binds clist_str_clone, clist_str_drop
+#define i_cmp -c_default_cmp // like std::greater<int>
#include <stc/csmap.h>
-void print(const Multimap mmap)
+void print(const char* lbl, const Multimap mmap)
{
+ printf("%s ", lbl);
c_foreach (e, Multimap, mmap) {
c_foreach (s, clist_str, e.ref->second)
printf("{%d,%s} ", e.ref->first, s.ref->str);
@@ -31,36 +33,41 @@ int main() c_auto (Multimap, mmap)
{
// list-initialize
- struct {int i; const char* s;} vals[] = {{2, "foo"}, {2, "bar"}, {3, "baz"}, {1, "abc"}, {5, "def"}};
- c_forrange (i, c_arraylen(vals)) insert(&mmap, vals[i].i, vals[i].s);
+ struct { int first; const char* second; } vals[] =
+ {{2, "foo"}, {2, "bar"}, {3, "baz"}, {1, "abc"}, {5, "def"}};
+ c_forrange (i, c_arraylen(vals)) insert(&mmap, c_pair(vals[i]));
+ print("#1", mmap);
// insert using value_type
insert(&mmap, 5, "pqr");
- print(mmap);
+ print("#2", mmap);
// insert using make_pair
insert(&mmap, 6, "uvw");
- print(mmap);
+ print("#3", mmap);
insert(&mmap, 7, "xyz");
- print(mmap);
+ print("#4", mmap);
// insert using initialization_list
insert(&mmap, 5, "one");
insert(&mmap, 5, "two");
- print(mmap);
+ print("#5", mmap);
+ // FOLLOWING NOT IN ORIGINAL EXAMPLE:
+
// erase all entries with key 5
Multimap_erase(&mmap, 5);
- print(mmap);
+ print("+6", mmap);
- // find and erase a specific entry
+ // find and erase first entry containing "bar"
clist_str_iter pos;
- c_foreach (e, Multimap, mmap)
+ c_foreach (e, Multimap, mmap) {
if ((pos = clist_str_find(&e.ref->second, "bar")).ref != clist_str_end(&e.ref->second).ref) {
clist_str_erase_at(&e.ref->second, pos);
break;
}
- print(mmap);
+ }
+ print("+7", mmap);
}
}
|
