summaryrefslogtreecommitdiffhomepage
path: root/docs/cbox_api.md
diff options
context:
space:
mode:
authorTyge Løvset <[email protected]>2021-12-12 21:33:22 +0100
committerTyge Løvset <[email protected]>2021-12-12 21:33:22 +0100
commitd57b9bb7666753c7cf7ab5a0da6d7d11f303c2af (patch)
tree258690df4a5ab62055261579967d6dfffaf5b0fd /docs/cbox_api.md
parent9cd20ebfc4f1e10153ff814085499223265ef902 (diff)
downloadSTC-modified-d57b9bb7666753c7cf7ab5a0da6d7d11f303c2af.tar.gz
STC-modified-d57b9bb7666753c7cf7ab5a0da6d7d11f303c2af.zip
- Added **cbox** type: container of one element: similar to std::unique_ptr / Rust Box.
- Replaced example for **csptr** in docs. - Added [**c_forpair**](docs/ccommon_api.md) macro: for-loop with "structural binding" as in c++. - Deprecated *csptr_X_make()*. Renamed to *csptr_X_new()*. Corresponding **cbox** method is *cbox_X_new()*. - Deprecated *c_default_fromraw(raw)*. Renamed to *c_default_clone(raw)*. - Deprecated `i_key_csptr` / `i_val_csptr`. Use `i_key_ref` / `i_val_ref` when specifying containers with **csptr** or **cbox** elements. - Deprecated `i_cnt`. Use `i_type` instead to define the full container type name. - Bugfixes and docs updates.
Diffstat (limited to 'docs/cbox_api.md')
-rw-r--r--docs/cbox_api.md136
1 files changed, 136 insertions, 0 deletions
diff --git a/docs/cbox_api.md b/docs/cbox_api.md
new file mode 100644
index 00000000..7c632919
--- /dev/null
+++ b/docs/cbox_api.md
@@ -0,0 +1,136 @@
+# STC [cbox](../include/stc/cbox.h): Shared Pointers
+
+**cbox** is a container for one heap allocated object. A **cbox** is empty by default.
+The *cbox_X_compare()*, *cbox_X_del()* methods are defined based on the `i_cmp`
+and `i_valdel` macros specified. Use *cbox_X_clone(p)* to make a deep copy, which
+uses the `i_valfrom` macro if defined.
+
+When declaring a container with cbox elements, define `i_val_ref` as the cbox type, see example.
+
+For containers, make sure to pass the result of create functions like *cbox_X_new()* **only** to
+*insert()*, *push_back()*, and *push()* functions. Use *emplace()* functions to deep clone
+already existing/owned cbox elements.
+
+See similar c++ class [std::unique_ptr](https://en.cppreference.com/w/cpp/memory/unique_ptr) for a functional reference, or Rust [std::boxed::Box](https://doc.rust-lang.org/std/boxed/struct.Box.html)
+
+## Header file and declaration
+
+```c
+#define i_val // value: REQUIRED
+#define i_cmp // three-way compare two i_val* : REQUIRED IF i_val is a non-integral type
+#define i_del // destroy value func - defaults to empty destruct
+#define i_tag // defaults to i_val
+#include <stc/cbox.h>
+```
+`X` should be replaced by the value of `i_tag` in all of the following documentation.
+
+## Methods
+```c
+cbox_X cbox_X_init(); // return an empty cbox
+cbox_X cbox_X_new(i_val val); // allocate new heap object with val. Take ownership of val.
+cbox_X cbox_X_from(i_rawval raw); // like cbox_X_new(), but create owned value from raw.
+cbox_X cbox_X_with(i_val* p); // create a cbox from a pointer. Takes ownership of p.
+
+cbox_X cbox_X_clone(cbox_X other); // return deep copied clone
+cbox_X cbox_X_move(cbox_X* self); // transfer ownership to another cbox.
+void cbox_X_take(cbox_X* self, cbox_X other); // take ownership of other.
+void cbox_X_copy(cbox_X* self, cbox_X other); // deep copy to self
+
+void cbox_X_del(cbox_X* self); // destruct the contained object and free's it.
+
+void cbox_X_reset(cbox_X* self);
+void cbox_X_reset_new(cbox_X* self, i_val val); // assign new cbox with value. Takes ownership of val.
+void cbox_X_reset_from(cbox_X* self, i_rawval raw); // make and assign new cbox from raw value.
+void cbox_X_reset_with(cbox_X* self, i_val* p); // create cbox with pointer p. Takes ownership of p.
+
+int cbox_X_compare(const cbox_X* x, const cbox_X* y); // compares pointer addresses if 'i_opt c_no_compare'
+ // is defined. Otherwise uses 'i_cmp' or default compare.
+```
+## Types and constants
+
+| Type name | Type definition | Used to represent... |
+|:-------------------|:--------------------------------|:------------------------|
+| `cbox_null` | `{NULL}` | Init nullptr const |
+| `cbox_X` | `struct { cbox_X_value* get; }` | The cbox type |
+| `cbox_X_value` | `i_val` | The cbox element type |
+
+## Example
+
+```c
+#include <stdio.h>
+#include <string.h>
+
+void int_del(int* x) {
+ printf("del: %d\n", *x);
+}
+
+// When 'i_del' is defined, you are also forced to define a clone function with
+// 'i_valfrom', as it is normally required when i_del destroys resources.
+//
+// If cloning is not needed, define 'i_opt c_no_clone' instead of 'i_valfrom'
+// both for the cbox type and the container of cbox elements. It will also
+// disable emplace container functions.
+//
+// This applies to all container types, except those with csptr elements, as they
+// define cloning internally.
+
+#define i_val int
+#define i_del int_del // optional func, just to display elements destroyed
+#define i_valfrom c_default_clone
+#include <stc/cbox.h> // cbox_int
+
+#define i_key_ref cbox_int // note: use i_key_ref instead of i_key
+#define i_tag int // tag otherwise defaults to 'ref'
+#include <stc/csset.h> // csset_int (like: std::set<std::unique_ptr<int>>)
+
+#define i_val_ref cbox_int // note: use i_val_ref instead of i_val
+#define i_tag int // tag otherwise defaults to 'ref'
+#include <stc/cvec.h> // cvec_int (like: std::vector<std::unique_ptr<int>>)
+
+int main()
+{
+ c_auto (cvec_int, vec) // declare and init vec, call del at scope exit
+ c_auto (csset_int, set) // declare and init set, call del at scope exit
+ {
+ c_apply(cvec_int, push_back, &vec, {
+ cbox_int_new(2021),
+ cbox_int_new(2012),
+ cbox_int_new(2022),
+ cbox_int_new(2015),
+ });
+ printf("vec:");
+ c_foreach (i, cvec_int, vec) printf(" %d", *i.ref->get);
+ puts("");
+
+ // add odd numbers from vec to set
+ c_foreach (i, cvec_int, vec)
+ if (*i.ref->get & 1)
+ csset_int_emplace(&set, *i.ref); // deep copy (clones) *i.ref object
+
+ // erase the two last elements in vec
+ cvec_int_pop_back(&vec);
+ cvec_int_pop_back(&vec);
+
+ printf("vec:");
+ c_foreach (i, cvec_int, vec) printf(" %d", *i.ref->get);
+
+ printf("\nset:");
+ c_foreach (i, csset_int, set) printf(" %d", *i.ref->get);
+
+ puts("\nDone");
+ }
+}
+```
+Output:
+```
+vec: 2021 2012 2022 2015
+del: 2015
+del: 2022
+vec: 2021 2012
+set: 2015 2021
+Done
+del: 2021
+del: 2015
+del: 2021
+del: 2012
+```