diff options
| -rw-r--r-- | docs/carray_api.md | 117 | ||||
| -rw-r--r-- | docs/cdeq_api.md | 14 | ||||
| -rw-r--r-- | docs/clist_api.md | 14 | ||||
| -rw-r--r-- | docs/cmap_api.md | 32 | ||||
| -rw-r--r-- | docs/cpque_api.md | 14 | ||||
| -rw-r--r-- | docs/cqueue_api.md | 14 | ||||
| -rw-r--r-- | docs/cset_api.md | 16 | ||||
| -rw-r--r-- | docs/csmap_api.md | 19 | ||||
| -rw-r--r-- | docs/csptr_api.md | 144 | ||||
| -rw-r--r-- | docs/csset_api.md | 14 | ||||
| -rw-r--r-- | docs/cstack_api.md | 14 | ||||
| -rw-r--r-- | docs/cvec_api.md | 14 | ||||
| -rw-r--r-- | examples/advanced.c | 2 | ||||
| -rw-r--r-- | include/stc/template.h | 45 |
14 files changed, 249 insertions, 224 deletions
diff --git a/docs/carray_api.md b/docs/carray_api.md index e8ca7ffc..ce3407ab 100644 --- a/docs/carray_api.md +++ b/docs/carray_api.md @@ -11,81 +11,84 @@ See the c++ class [boost::multi_array](https://www.boost.org/doc/libs/release/li ## Header file and declaration ```c -#include <stc/carray.h> - -using_carray2(X, Value); -using_carray2(X, Value, valueDel, valueClone); -using_carray3(X, Value); -using_carray3(X, Value, valueDel, valueClone); +#define i_tag // defaults to i_val name +#define i_val // value: REQUIRED +#define i_cmp // three-way compare two i_valraw* : REQUIRED IF i_valraw is a non-integral type +#define i_valraw // convertion "raw" type - defaults to i_val +#define i_valfrom // convertion func i_valraw => i_val - defaults to plain copy +#define i_valdel // destroy value func - defaults to empty destruct + +#include <stc/carr2.h> // or <stc/carr3.h> ``` -The macro `using_carray2()` must be instantiated in the global scope. `X` and `N` are type tags and -will affect the names of all cset types and methods. E.g. declaring `using_carray3(i, int);`, `X` should -be replaced by `i` in all of the following documentation. +`X` should be replaced by the value of i_tag in all of the following documentation. -```c -#include <stc/carray.h> -``` ## Methods +carr2_X: ```c -carray2X carray2X_init(size_t xdim, size_t ydim); -carray2X carray2X_with_values(size_t xdim, size_t ydim, Value val); -carray2X carray2X_with_storage(size_t xdim, size_t ydim, Value* array); -carray2X carray2X_clone(carray2X arr); -Value* carray2X_release(carray2X* self); // release storage (not freed) -void carray2X_del(carray2X* self); - -size_t carray2X_size(carray2X arr); -Value* carray2X_data(carray2X* self); // access storage data -Value* carray2X_at(carray2X* self, size_t x, size_t y); - -carray2X_iter_t carray2X_begin(const carray2X* self); -carray2X_iter_t carray2X_end(const carray2X* self); -void carray2X_next(carray2X_iter_t* it); +carr2_X carr2_X_init(size_t xdim, size_t ydim); +carr2_X carr2_X_with_values(size_t xdim, size_t ydim, Value val); +carr2_X carr2_X_with_storage(size_t xdim, size_t ydim, Value* array); +carr2_X carr2_X_clone(carr2_X arr); +Value* carr2_X_release(carr2_X* self); // release storage (not freed) +void carr2_X_del(carr2_X* self); + +size_t carr2_X_size(carr2_X arr); +Value* carr2_X_data(carr2_X* self); // access storage data +Value* carr2_X_at(carr2_X* self, size_t x, size_t y); + +carr2_X_iter_t carr2_X_begin(const carr2_X* self); +carr2_X_iter_t carr2_X_end(const carr2_X* self); +void carr2_X_next(carr2_X_iter_t* it); ``` +carr3: ```c -carray3X carray3X_init(size_t xdim, size_t ydim, size_t zdim); -carray3X carray3X_with_values(size_t xdim, size_t ydim, size_t zdim, Value val); -carray3X carray3X_with_storage(size_t xdim, size_t ydim, size_t zdim, Value* array); -carray3X carray3X_clone(carray3X arr); -Value* carray3X_release(carray3X* self); // release storage (not freed) -void carray3X_del(carray3X* self); - -size_t carray3X_size(carray3X arr); -Value* carray3X_data(carray3X* self); // access storage data -Value* carray3X_at(carray3X* self, size_t x, size_t y, size_t z); - -carray3X_iter_t carray3X_begin(const carray3X* self); -carray3X_iter_t carray3X_end(const carray3X* self); -void carray3X_next(carray3X_iter_t* it); +carr3_X carr3_X_init(size_t xdim, size_t ydim, size_t zdim); +carr3_X carr3_X_with_values(size_t xdim, size_t ydim, size_t zdim, Value val); +carr3_X carr3_X_with_storage(size_t xdim, size_t ydim, size_t zdim, Value* array); +carr3_X carr3_X_clone(carr3_X arr); +Value* carr3_X_release(carr3_X* self); // release storage (not freed) +void carr3_X_del(carr3_X* self); + +size_t carr3_X_size(carr3_X arr); +Value* carr3_X_data(carr3_X* self); // access storage data +Value* carr3_X_at(carr3_X* self, size_t x, size_t y, size_t z); + +carr3_X_iter_t carr3_X_begin(const carr3_X* self); +carr3_X_iter_t carr3_X_end(const carr3_X* self); +void carr3_X_next(carr3_X_iter_t* it); ``` ## Types -| Type name | Type definition | Used to represent... | -|:---------------------|:-----------------------------------------------------|:--------------------------| -| `carray2X` | `struct { Value **data; size_t xdim, ydim; }` | The carray2 type | -| `carray2X_value_t` | `Value` | The value type | -| `carray2X_iter_t` | `struct { Value *ref; }` | Iterator type | -| `carray3X` | `struct { Value ***data; size_t xdim, ydim, zdim; }` | The carray3 type | -| `carray3X_value_t` | `Value` | The value type | -| `carray3X_iter_t` | `struct { Value *ref; }` | Iterator type | +| Type name | Type definition | Used to represent... | +|:------------------|:-----------------------------------------------------|:---------------------| +| `carr2_X` | `struct { Value **data; size_t xdim, ydim; }` | The carray2 type | +| `carr2_X_value_t` | `Value` | The value type | +| `carr2_X_iter_t` | `struct { Value *ref; }` | Iterator type | +| `carr3_X` | `struct { Value ***data; size_t xdim, ydim, zdim; }` | The carray3 type | +| `carr3_X_value_t` | `Value` | The value type | +| `carr3_X_iter_t` | `struct { Value *ref; }` | Iterator type | The **carray** elements can be accessed like `carray3i arr = ...; int val = arr.data[x][y][z];`, or with `carray3i_at(&arr, x, y, z)`. ## Example ```c #include <stdio.h> -#include <stc/carray.h> -using_carray3(f, float); -using_carray2(i, uint32_t); +#define i_tag i +#define i_val uint32_t +#include <stc/carr2.h> + +#define i_tag f +#define i_val float +#include <stc/carr3.h> int main() { // Ex1 int xd = 30, yd = 20, zd = 10; // define arr3[30][20][10], initialized with zeros. - carray3f arr3 = carray3f_with_values(xd, yd, zd, 0.0f); + carr3_f arr3 = carr3_f_with_values(xd, yd, zd, 0.0f); arr3.data[5][4][3] = 3.14f; float *arr1 = arr3.data[5][4]; @@ -94,20 +97,20 @@ int main() printf("%f\n", arr1[3]); // 3.14 printf("%f\n", arr2[4][3]); // 3.14 printf("%f\n", arr3.data[5][4][3]); // 3.14 - carray3f_del(&arr3); // free array + carr3_f_del(&arr3); // free array // Ex2 int w = 256, h = 128; - carray2i image = carray2i_init(w, h); + carr2_i image = carr2_i_init(w, h); int n = 0; - c_foreach (i, carray2i, image) { + c_foreach (i, carr2_i, image) { uint32_t t = n++ % 256; *i.ref = t | t << 8 | t << 16 | 255; } - for (int y=0; y<image.ydim; ++y) + for (int y = 0; y < image.ydim; ++y) image.data[y][y] = 0xffffffff; - carray2i_del(&image); + carr2_i_del(&image); } ``` Output: diff --git a/docs/cdeq_api.md b/docs/cdeq_api.md index a79b6d4c..1ad754a1 100644 --- a/docs/cdeq_api.md +++ b/docs/cdeq_api.md @@ -8,13 +8,13 @@ See the c++ class [std::deque](https://en.cppreference.com/w/cpp/container/deque ## Header file and declaration ```c -#define i_tag -#define i_val // required -#define i_cmp // required if i_val is a struct -#define i_valdel -#define i_valfrom -#define i_valto -#define i_valraw +#define i_tag // defaults to i_val name +#define i_val // value: REQUIRED +#define i_cmp // three-way compare two i_valraw* : REQUIRED IF i_valraw is a non-integral type +#define i_valraw // convertion "raw" type - defaults to i_val +#define i_valfrom // convertion func i_valraw => i_val - defaults to plain copy +#define i_valto // convertion func i_val* => i_valraw - defaults to plain copy +#define i_valdel // destroy value func - defaults to empty destruct #include <stc/cdeq.h> ``` `X` should be replaced by the value of i_tag in all of the following documentation. diff --git a/docs/clist_api.md b/docs/clist_api.md index b4f1d750..3f866815 100644 --- a/docs/clist_api.md +++ b/docs/clist_api.md @@ -22,13 +22,13 @@ See the c++ class [std::list](https://en.cppreference.com/w/cpp/container/list) ## Header file and declaration ```c -#define i_tag -#define i_val // required -#define i_cmp // required if i_val is a struct -#define i_valdel -#define i_valfrom -#define i_valto -#define i_valraw +#define i_tag // defaults to i_val name +#define i_val // value: REQUIRED +#define i_cmp // three-way compare two i_valraw* : REQUIRED IF i_valraw is a non-integral type +#define i_valraw // convertion "raw" type - defaults to i_val +#define i_valfrom // convertion func i_valraw => i_val - defaults to plain copy +#define i_valto // convertion func i_val* => i_valraw - defaults to plain copy +#define i_valdel // destroy value func - defaults to empty destruct #include <stc/clist.h> ``` diff --git a/docs/cmap_api.md b/docs/cmap_api.md index 28ffc872..f84a4aef 100644 --- a/docs/cmap_api.md +++ b/docs/cmap_api.md @@ -17,13 +17,19 @@ See the c++ class [std::unordered_map](https://en.cppreference.com/w/cpp/contain ## Header file and declaration ```c -#define i_tag -#define i_val // required -#define i_cmp // required if i_val is a struct -#define i_valdel -#define i_valfrom -#define i_valto -#define i_valraw +#define i_tag // defaults to i_key name +#define i_key // key: REQUIRED +#define i_val // value: REQUIRED +#define i_equ // equality comparison two i_keyraw*. REQUIRED IF i_keyraw is non-integral type +#define i_cmp // three-way compare two i_keyraw* : may be defined instead of i_equ +#define i_keyraw // convertion "raw" type - defaults to i_key +#define i_keyfrom // convertion func i_keyraw => i_key - defaults to plain copy +#define i_keyto // convertion func i_key* => i_keyraw - defaults to plain copy +#define i_keydel // destroy key func - defaults to empty destruct +#define i_valraw // convertion "raw" type - defaults to i_val +#define i_valfrom // convertion func i_valraw => i_val - defaults to plain copy +#define i_valto // convertion func i_val* => i_valraw - defaults to plain copy +#define i_valdel // destroy value func - defaults to empty destruct #include <stc/cmap.h> ``` `X` should be replaced by the value of i_tag in all of the following documentation. @@ -277,9 +283,9 @@ static void Viking_del(Viking* v) { #define i_tag vk #define i_key Viking #define i_val int -#define i_valdel Viking_del #define i_equ Viking_equals #define i_hash Viking_hash +#define i_keydel Viking_del #include <stc/cmap.h> int main() @@ -347,12 +353,12 @@ static RViking Viking_toR(const Viking* v) {return (RViking){v->name.str, v->cou #define i_tag vk #define i_key Viking #define i_val int -#define i_valdel Viking_del -#define i_valraw RViking #define i_equ RViking_equals #define i_hash RViking_hash +#define i_keyraw RViking #define i_keyfrom Viking_fromR #define i_keyto Viking_toR +#define i_keydel Viking_del #include <stc/cmap.h> int main() @@ -364,14 +370,14 @@ int main() cmap_vk_insert(&vikings, (Viking){cstr_from("Einar"), cstr_from("Norway")}, 25); cmap_vk_insert(&vikings, (Viking){cstr_from("Olaf"), cstr_from("Denmark")}, 24); - // emplace is simple to use now. + // but emplace is simpler to use now. cmap_vk_emplace(&vikings, (RViking){"Harald", "Iceland"}, 12); cmap_vk_emplace(&vikings, (RViking){"Einar", "Denmark"}, 21); - // And lookup uses "raw" key type, so no need construct/destruct key: + // and lookup uses "raw" key type, so no need construct/destruct key: printf("Lookup: Einar of Norway has %d hp\n\n", *cmap_vk_at(&vikings, (RViking){"Einar", "Norway"})); - // Print the status of the vikings. + // print the status of the vikings. c_foreach (i, cmap_vk, vikings) { printf("%s of %s has %d hp\n", i.ref->first.name.str, i.ref->first.country.str, i.ref->second); } diff --git a/docs/cpque_api.md b/docs/cpque_api.md index dba3fe3a..343215bf 100644 --- a/docs/cpque_api.md +++ b/docs/cpque_api.md @@ -8,13 +8,13 @@ See the c++ class [std::priority_queue](https://en.cppreference.com/w/cpp/contai ## Header file and declaration ```c -#define i_tag -#define i_val // required -#define i_cmp // required if i_val is a struct -#define i_valdel -#define i_valfrom -#define i_valto -#define i_valraw +#define i_tag // defaults to i_val name +#define i_val // value: REQUIRED +#define i_cmp // three-way compare two i_valraw* : REQUIRED IF i_valraw is a non-integral type +#define i_valraw // convertion "raw" type - defaults to i_val +#define i_valfrom // convertion func i_valraw => i_val - defaults to plain copy +#define i_valto // convertion func i_val* => i_valraw - defaults to plain copy +#define i_valdel // destroy value func - defaults to empty destruct #include <stc/cpque.h> ``` `X` should be replaced by the value of i_tag in all of the following documentation. diff --git a/docs/cqueue_api.md b/docs/cqueue_api.md index eb1450a3..16e87d47 100644 --- a/docs/cqueue_api.md +++ b/docs/cqueue_api.md @@ -7,13 +7,13 @@ See the c++ class [std::queue](https://en.cppreference.com/w/cpp/container/queue ## Header file and declaration ```c -#define i_tag -#define i_val // required -#define i_cmp // required if i_val is a struct -#define i_valdel -#define i_valfrom -#define i_valto -#define i_valraw +#define i_tag // defaults to i_val name +#define i_val // value: REQUIRED +#define i_cmp // three-way compare two i_valraw* : REQUIRED IF i_valraw is a non-integral type +#define i_valraw // convertion "raw" type - defaults to i_val +#define i_valfrom // convertion func i_valraw => i_val - defaults to plain copy +#define i_valto // convertion func i_val* => i_valraw - defaults to plain copy +#define i_valdel // destroy value func - defaults to empty destruct #include <stc/cqueue.h> ``` `X` should be replaced by the value of i_tag in all of the following documentation. diff --git a/docs/cset_api.md b/docs/cset_api.md index fc12c5bd..8b645d29 100644 --- a/docs/cset_api.md +++ b/docs/cset_api.md @@ -7,13 +7,15 @@ A **cset** is an associative container that contains a set of unique objects of ## Header file and declaration
```c
-#define i_tag
-#define i_val // required
-#define i_cmp // required if i_val is a struct
-#define i_valdel
-#define i_valfrom
-#define i_valto
-#define i_valraw
+#define i_tag // defaults to i_key name
+#define i_key // key: REQUIRED
+#define i_hash // hash func: REQUIRED IF i_keyraw is a non-pod type
+#define i_equ // equality comparison two i_keyraw*. REQUIRED IF i_keyraw is a non-integral type
+#define i_cmp // three-way compare two i_keyraw* : alternative to i_equ
+#define i_keyraw // convertion "raw" type - defaults to i_key
+#define i_keyfrom // convertion func i_keyraw => i_key - defaults to plain copy
+#define i_keyto // convertion func i_key* => i_keyraw - defaults to plain copy
+#define i_keydel // destroy key func - defaults to empty destruct
#include <stc/cset.h>
```
`X` should be replaced by the value of i_tag in all of the following documentation.
diff --git a/docs/csmap_api.md b/docs/csmap_api.md index 6fdd3857..338758ce 100644 --- a/docs/csmap_api.md +++ b/docs/csmap_api.md @@ -15,13 +15,18 @@ See the c++ class [std::map](https://en.cppreference.com/w/cpp/container/map) fo ## Header file and declaration ```c -#define i_tag -#define i_val // required -#define i_cmp // required if i_val is a struct -#define i_valdel -#define i_valfrom -#define i_valto -#define i_valraw +#define i_tag // defaults to i_key name +#define i_key // value: REQUIRED +#define i_val // key: REQUIRED +#define i_cmp // three-way compare two i_keyraw* : REQUIRED IF i_keyraw is a non-integral type +#define i_keyraw // convertion "raw" type - defaults to i_key +#define i_keyfrom // convertion func i_keyraw => i_key - defaults to plain copy +#define i_keyto // convertion func i_key* => i_keyraw - defaults to plain copy +#define i_keydel // destroy key func - defaults to empty destruct +#define i_valraw // convertion "raw" type - defaults to i_val +#define i_valfrom // convertion func i_valraw => i_val - defaults to plain copy +#define i_valto // convertion func i_val* => i_valraw - defaults to plain copy +#define i_valdel // destroy value func - defaults to empty destruct #include <stc/csmap.h> ``` `X` should be replaced by the value of i_tag in all of the following documentation. diff --git a/docs/csptr_api.md b/docs/csptr_api.md index a7f37481..afef2154 100644 --- a/docs/csptr_api.md +++ b/docs/csptr_api.md @@ -21,13 +21,10 @@ See the c++ classes [std::shared_ptr](https://en.cppreference.com/w/cpp/memory/s ## Header file and declaration ```c -#define i_tag -#define i_val // required -#define i_cmp // required if i_val is a struct -#define i_valdel -#define i_valfrom -#define i_valto -#define i_valraw +#define i_tag // defaults to i_val name +#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_valdel // destroy value func - defaults to empty destruct #include <stc/csptr.h> ``` `X` should be replaced by the value of i_tag in all of the following documentation. @@ -69,30 +66,31 @@ bool csptr_X_equals(const csptr_X* x, const csptr_X* y); ## Example ```c -#include <stc/csptr.h> #include <stc/cstr.h> -typedef struct { cstr name, last; } Person; +typedef struct { cstr name, surname; } Person; -Person Person_init(const char* name, const char* last) { - return (Person){.name = cstr_from(name), .last = cstr_from(last)}; +Person Person_init(const char* name, const char* surname) { + return (Person){.name = cstr_from(name), .surname = cstr_from(surname)}; } void Person_del(Person* p) { - printf("Destroy: %s %s\n", p->name.str, p->last.str); - c_del(cstr, &p->name, &p->last); + printf("Person_del: %s %s\n", p->name.str, p->surname.str); + c_del(cstr, &p->name, &p->surname); } - -using_csptr(person, Person, c_no_compare, Person_del); +#define i_val Person +#define i_cmp c_no_compare +#define i_valdel Person_del +#include <stc/csptr.h> int main() { csptr_person p = csptr_person_make(Person_init("John", "Smiths")); csptr_person q = csptr_person_clone(p); // means: share the pointer - printf("Person: %s %s. uses: %zu\n", p.get->name.str, p.get->last.str, *p.use_count); + printf("Person: %s %s. uses: %zu\n", p.get->name.str, p.get->surname.str, *p.use_count); csptr_person_del(&p); - printf("Last man standing: %s %s. uses: %zu\n", q.get->name.str, q.get->last.str, *q.use_count); + printf("Last man standing: %s %s. uses: %zu\n", q.get->name.str, q.get->surname.str, *q.use_count); csptr_person_del(&q); } ``` @@ -100,38 +98,37 @@ Output: ``` Person: John Smiths. uses: 2 Last man standing: John Smiths. uses: 1 -Destroy: John Smiths +Person_del: John Smiths ``` ### Example 2 -Advanced: Two different ways to store Person in vectors: 1) `cvec<Person>`, 2) `cvec< csptr<Person> >`. +Vector of shared pointers to Person: ```c -#include <stc/csptr.h> #include <stc/cstr.h> -#include <stc/cvec.h> -typedef struct { cstr name, last; } Person; +typedef struct { cstr name, surname; } Person; -Person* Person_make(Person* p, const char* name, const char* last) { - p->name = cstr_from(name), p->last = cstr_from(last); - return p; -} -int Person_compare(const Person* p, const Person* q) { - int cmp = strcmp(p->name.str, q->name.str); - return cmp == 0 ? strcmp(p->last.str, q->last.str) : cmp; +Person Person_init(const char* name, const char* surname) { + return (Person){.name = cstr_from(name), .surname = cstr_from(surname)}; } void Person_del(Person* p) { - printf("del: %s\n", p->name.str); - c_del(cstr, &p->name, &p->last); + printf("Person_del: %s %s\n", p->name.str, p->surname.str); + c_del(cstr, &p->name, &p->surname); +} +int Person_compare(const Person* p, const Person* q) { + int cmp = strcmp(p->surname.str, q->surname.str); + return cmp == 0 ? strcmp(p->name.str, q->name.str) : cmp; } -// 1. cvec of Person struct; emplace and cloning disabled. -using_cvec(pe, Person, Person_compare, Person_del, c_no_clone); +#define i_tag pers +#define i_val Person +#define i_cmp Person_compare +#define i_valdel Person_del +#include <stc/csptr.h> -// 2. cvec of shared-ptr to Person - with emplace_back() and cloning cvec ENABLED. -using_csptr(pe, Person, Person_compare, Person_del); -using_cvec(ps, csptr_pe, csptr_pe_compare, csptr_pe_del, csptr_pe_clone); +#define i_val_csptr pers // shorthand: derives other i_xxx defines from this. i_tag may be defined. +#include <stc/cvec.h> const char* names[] = { "Joe", "Jordan", @@ -140,60 +137,43 @@ const char* names[] = { }; int main() { - cvec_pe vec1 = cvec_pe_init(); - cvec_ps vec2 = cvec_ps_init(); + cvec_pers vec = cvec_pers_init(); - for (int i = 0; i < 6; i += 2) { - Person tmp; - cvec_pe_push_back(&vec1, *Person_make(&tmp, names[i], names[i+1])); - cvec_ps_push_back(&vec2, csptr_pe_from(Person_make(c_new(Person), names[i], names[i+1]))); + for (int i = 0; i < c_arraylen(names); i += 2) { + cvec_pers_push_back(&vec, csptr_pers_make(Person_init(names[i], names[i+1]))); } - puts("1. Sorted vec1 of Person:"); - cvec_pe_sort(&vec1); - c_foreach (i, cvec_pe, vec1) - printf(" %s %s\n", i.ref->name.str, i.ref->last.str); - - // Append a shared copy of vec2.data[0]. Will only be destructed once! - cvec_ps_emplace_back(&vec2, vec2.data[0]); // emplace will internally call csptr_ps_clone()! - puts("\n2. Sorted vec2 of shared-pointer to Person:"); - cvec_ps_sort(&vec2); - c_foreach (i, cvec_ps, vec2) - printf(" %s %s\n", i.ref->get->name.str, i.ref->get->last.str); - - // Share vec2.data[1] with elem1 variable. - csptr_pe elem1 = csptr_pe_clone(vec2.data[1]); - - puts("\nDestroy vec1:"); - cvec_pe_del(&vec1); - puts("\nDestroy vec2:"); - cvec_ps_del(&vec2); + + // Append a shared copy of vec.data[0]. Will only be destructed once! + cvec_pers_emplace_back(&vec, vec.data[0]); // will internally call csptr_pers_clone()! + + puts("\nSorted vec of shared-pointer to Person:"); + cvec_pers_sort(&vec); + + c_foreach (i, cvec_pers, vec) + printf(" %s, %s\n", i.ref->get->surname.str, i.ref->get->name.str); + + // Share vec.data[1] with elem1 variable. + csptr_pers elem1 = csptr_pers_clone(vec.data[1]); + + puts("\nDestroy vec:"); + cvec_pers_del(&vec); puts("\nDestroy elem1:"); - csptr_pe_del(&elem1); + csptr_pers_del(&elem1); } ``` Output: ``` -1. Sorted vec1 of Person: - Annie Aniston - Jane Jacobs - Joe Jordan - -2. Sorted vec2 of shared-pointer to Person: - Annie Aniston - Jane Jacobs - Joe Jordan - Joe Jordan - -Destroy vec1: -del: Annie -del: Jane -del: Joe - -Destroy vec2: -del: Annie -del: Joe +Sorted vec of shared-pointer to Person: + Aniston, Annie + Jacobs, Jane + Jordan, Joe + Jordan, Joe + +Destroy vec: +Person_del: Annie Aniston +Person_del: Joe Jordan Destroy elem1: -del: Jane +Person_del: Jane Jacobs ``` diff --git a/docs/csset_api.md b/docs/csset_api.md index 8bf83a17..0fdb8086 100644 --- a/docs/csset_api.md +++ b/docs/csset_api.md @@ -8,13 +8,13 @@ See the c++ class [std::set](https://en.cppreference.com/w/cpp/container/set) fo ## Header file and declaration
```c
-#define i_tag
-#define i_val // required
-#define i_cmp // required if i_val is a struct
-#define i_valdel
-#define i_valfrom
-#define i_valto
-#define i_valraw
+#define i_tag // defaults to i_key name
+#define i_key // key: REQUIRED
+#define i_cmp // three-way compare two i_keyraw* : REQUIRED IF i_keyraw is a non-integral type
+#define i_keyraw // convertion "raw" type - defaults to i_key
+#define i_keyfrom // convertion func i_keyraw => i_key - defaults to plain copy
+#define i_keyto // convertion func i_key* => i_keyraw - defaults to plain copy
+#define i_keydel // destroy key func - defaults to empty destruct
#include <stc/csset.h>
```
`X` should be replaced by the value of i_tag in all of the following documentation.
diff --git a/docs/cstack_api.md b/docs/cstack_api.md index b971811c..68f22b57 100644 --- a/docs/cstack_api.md +++ b/docs/cstack_api.md @@ -8,13 +8,13 @@ See the c++ class [std::stack](https://en.cppreference.com/w/cpp/container/stack ## Header file and declaration ```c -#define i_tag -#define i_val // required -#define i_cmp // required if i_val is a struct -#define i_valdel -#define i_valfrom -#define i_valto -#define i_valraw +#define i_tag // defaults to i_val name +#define i_val // value: REQUIRED +#define i_cmp // three-way compare two i_valraw* : REQUIRED IF i_valraw is a non-integral type +#define i_valraw // convertion "raw" type - defaults to i_val +#define i_valfrom // convertion func i_valraw => i_val - defaults to plain copy +#define i_valto // convertion func i_val* => i_valraw - defaults to plain copy +#define i_valdel // destroy value func - defaults to empty destruct #include <stc/cstack.h> ``` `X` should be replaced by the value of i_tag in all of the following documentation. diff --git a/docs/cvec_api.md b/docs/cvec_api.md index e04c0a8d..07164e46 100644 --- a/docs/cvec_api.md +++ b/docs/cvec_api.md @@ -12,13 +12,13 @@ See the c++ class [std::vector](https://en.cppreference.com/w/cpp/container/vect ## Header file and declaration ```c -#define i_tag -#define i_val // required -#define i_cmp // required if i_val is a struct -#define i_valdel -#define i_valfrom -#define i_valto -#define i_valraw +#define i_tag // defaults to i_val name +#define i_val // value: REQUIRED +#define i_cmp // three-way compare two i_valraw* : REQUIRED IF i_valraw is a non-integral type +#define i_valraw // convertion "raw" type - defaults to i_val +#define i_valfrom // convertion func i_valraw => i_val - defaults to plain copy +#define i_valto // convertion func i_val* => i_valraw - defaults to plain copy +#define i_valdel // destroy value func - defaults to empty destruct #include <stc/cvec.h> ``` `X` should be replaced by the value of i_tag in all of the following documentation. diff --git a/examples/advanced.c b/examples/advanced.c index 5d54275f..8044594e 100644 --- a/examples/advanced.c +++ b/examples/advanced.c @@ -39,10 +39,10 @@ static inline VikingRaw viking_toRaw(const Viking* vk) { #define i_val int #define i_equ vikingraw_equals #define i_hash vikingraw_hash -#define i_keydel viking_del #define i_keyraw VikingRaw #define i_keyfrom viking_fromRaw #define i_keyto viking_toRaw +#define i_keydel viking_del #include <stc/cmap.h> int main() diff --git a/include/stc/template.h b/include/stc/template.h index dc83c167..b255d647 100644 --- a/include/stc/template.h +++ b/include/stc/template.h @@ -29,7 +29,7 @@ #define Self c_PASTE(i_prefix, i_tag)
// typedef container types defined in forward.h. VC requires c_EXPAND.
#define cx_deftypes(macro, SELF, ...) c_EXPAND(macro(SELF, __VA_ARGS__))
-
+
#define cx_value_t cx_memb(_value_t)
#define cx_key_t cx_memb(_key_t)
#define cx_mapped_t cx_memb(_mapped_t)
@@ -47,10 +47,36 @@ #define i_fwd
#endif
+#ifndef i_prefix_csptr
+#define i_prefix_csptr csptr_
+#endif
+#ifdef i_key_csptr
+ #ifndef i_tag
+ #define i_tag i_key_csptr
+ #endif
+ #define i_key c_PASTE(i_prefix_csptr, i_key_csptr)
+ #define i_cmp c_PASTE3(i_prefix_csptr, i_key_csptr, _compare)
+ #define i_keydel c_PASTE3(i_prefix_csptr, i_key_csptr, _del)
+ #define i_keyfrom c_PASTE3(i_prefix_csptr, i_key_csptr, _clone)
+#endif
+#ifdef i_val_csptr
+ #if !defined i_tag && !defined i_key
+ #define i_tag i_val_csptr
+ #endif
+ #define i_val c_PASTE(i_prefix_csptr, i_val_csptr)
+ #ifndef i_key
+ #define i_cmp c_PASTE3(i_prefix_csptr, i_val_csptr, _compare)
+ #endif
+ #define i_valdel c_PASTE3(i_prefix_csptr, i_val_csptr, _del)
+ #define i_valfrom c_PASTE3(i_prefix_csptr, i_val_csptr, _clone)
+#endif
+
#ifdef i_key_str
#define i_key cstr
+ #ifndef i_tag
+ #define i_tag str
+ #endif
#define i_cmp c_rawstr_compare
- #define i_equ c_rawstr_equals
#define i_hash c_rawstr_hash
#define i_keydel cstr_del
#define i_keyfrom cstr_from
@@ -59,6 +85,9 @@ #endif
#ifdef i_val_str
#define i_val cstr
+ #if !defined i_tag && !defined i_key
+ #define i_tag str
+ #endif
#ifndef i_key
#define i_cmp c_rawstr_compare
#endif
@@ -67,16 +96,13 @@ #define i_valto cstr_str
#define i_valraw const char*
#endif
+
#if defined i_key && !defined i_val
#define i_val i_key
#endif
-#if !defined i_tag && defined i_key_str
- #define i_tag str
-#elif !defined i_tag && defined i_key
+#if !defined i_tag && defined i_key
#define i_tag i_key
-#elif !defined i_tag && defined i_val_str
- #define i_tag str
-#elif !defined i_tag && defined i_val
+#elif !defined i_tag
#define i_tag i_val
#endif
@@ -148,6 +174,9 @@ #undef i_keyfrom
#undef i_keyto
#undef i_keyraw
+#undef i_key_csptr
+#undef i_val_csptr
+#undef i_prefix_csptr
#undef i_template
#endif
|
