From 7b975a71e5c07d8ff92ae68334e888f4e1d28b6e Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Wed, 17 Feb 2021 20:20:56 +0100 Subject: Updated cptr.h examples. --- docs/cmap_api.md | 2 +- docs/cptr_api.md | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++- examples/csmap_ex.c | 61 --------------------------------------- examples/csmap_ex2.c | 74 ------------------------------------------------ examples/ptr.c | 80 ---------------------------------------------------- stc/cptr.h | 17 +++++------ 6 files changed, 86 insertions(+), 227 deletions(-) delete mode 100644 examples/csmap_ex.c delete mode 100644 examples/csmap_ex2.c delete mode 100644 examples/ptr.c diff --git a/docs/cmap_api.md b/docs/cmap_api.md index b789944c..a272e1c8 100644 --- a/docs/cmap_api.md +++ b/docs/cmap_api.md @@ -260,7 +260,7 @@ Output: ``` ### Example 5 -Demonstrate a complex key type. +Advanced only: Demonstrate use of a complex key type. ```c #include #include diff --git a/docs/cptr_api.md b/docs/cptr_api.md index f1fd0cf1..09e63d5e 100644 --- a/docs/cptr_api.md +++ b/docs/cptr_api.md @@ -66,7 +66,84 @@ int csptr_X_compare(csptr_X* x, csptr_X* y); ## Example -This example shows three different ways to store struct Person in vectors: 1) `cvec`, 2) `cvec`, and 3) `cvec>`. +Managed raw pointers (cptr) in a cvec. +```c +#include +#include +#include + +typedef struct { cstr_t name, last; } Person; + +Person* Person_make(Person* p, const char* name, const char* last) { + p->name = cstr_from(name), p->last = cstr_from(last); + return p; +} +void Person_del(Person* p) { + printf("Destroy: %s %s\n", p->name.str, p->last.str); + c_del(cstr, &p->name, &p->last); +} +// declare managed pointer and cvec with pointers +using_cptr(pe, Person, c_no_compare, Person_del, c_no_clone); +using_cvec(pe, Person*, c_no_compare, cptr_pe_del, c_no_clone); + +int main() { + cvec_pe vec = cvec_pe_init(); + cvec_pe_push_back(&vec, Person_make(c_new(Person), "John", "Smiths")); + cvec_pe_push_back(&vec, Person_make(c_new(Person), "Jane", "Doe")); + + c_foreach (i, cvec_pe, vec) + printf("%s %s\n", (*i.ref)->name.str, (*i.ref)->last.str); + cvec_pe_del(&vec); +} +``` +Output: +``` +Average Joe +Joe Blow +Destroy: Average Joe +Destroy: Joe Blow +``` +## Example 2 + +Simple shared pointer (csptr) usage. +```c +#include +#include + +typedef struct { cstr_t name, last; } Person; + +Person* Person_make(Person* p, const char* name, const char* last) { + p->name = cstr_from(name), p->last = cstr_from(last); + return p; +} +void Person_del(Person* p) { + printf("Destroy: %s %s\n", p->name.str, p->last.str); + c_del(cstr, &p->name, &p->last); +} + +using_csptr(pe, Person, c_no_compare, Person_del); + +int main() { + csptr_pe p = csptr_pe_from(Person_make(c_new(Person), "John", "Smiths")); + csptr_pe q = csptr_pe_clone(p); // means: share the pointer + + printf("Person: %s %s. uses: %zu\n", p.get->name.str, p.get->last.str, *p.use_count); + csptr_pe_del(&p); + + printf("Last man standing: %s %s. uses: %zu\n", q.get->name.str, q.get->last.str, *q.use_count); + csptr_pe_del(&q); +} +``` +Output: +``` +Person: John Smiths. uses: 2 +Last man standing: John Smiths. uses: 1 +Destroy: John Smiths +``` + +### Example 2 + +Advanced: Three different ways to store Person in vectors: 1) `cvec`, 2) `cvec`, and 3) `cvec>`. ```c #include #include diff --git a/examples/csmap_ex.c b/examples/csmap_ex.c deleted file mode 100644 index 032400f9..00000000 --- a/examples/csmap_ex.c +++ /dev/null @@ -1,61 +0,0 @@ -#include -#include -#include -#include - -using_csmap(i, int, size_t); -using_csset_str(); - -#include - -int main(int argc, char **argv) -{ - size_t n = 1000000; - - csmap_i map = csmap_i_with_capacity(n); - time_t seed = time(NULL); - - uint64_t mask = (1ull << 31) - 1; - csmap_i_iter_t it; - - stc64_srandom(seed); - c_forrange (i, n) { - uint64_t val = stc64_random() & mask; - csmap_i_emplace(&map, val, i); - } - printf("size1: %zu, %zu\n", csmap_i_size(map), csmap_i_capacity(map)); - stc64_srandom(seed); - c_forrange (n - 20) - csmap_i_erase(&map, stc64_random() & mask); - - size_t val = 500000; - c_forrange (i, n) { - uint64_t val = stc64_random() & mask; - csmap_i_emplace(&map, val, i); - } - - printf("size2: %zu, %zu\n", csmap_i_size(map), csmap_i_capacity(map)); - - int k = 0; - c_foreach (i, csmap_i, map) - if (k < 20) printf("%2d %d: %zu\n", ++k, i.ref->first, i.ref->second); - - csmap_i_find_it(&map, val, &it); - printf("\nmin/max: %d -- %d: found: %d. size: %zu\n", csmap_i_front(&map)->first, - csmap_i_back(&map)->first, - it.ref->first, - csmap_i_size(map)); - c_foreach (i, csmap_i, it, csmap_i_end(&map)) - printf("-- %d: %zu\n", i.ref->first, i.ref->second); - - csmap_i_del(&map); - puts(""); - - - c_init (csset_str, shouts, {"Hello", "Try this", "Awesome", "Works well", "Greetings"}); - - c_foreach (i, csset_str, shouts) - printf("shout: %s\n", i.ref->str); - - csset_str_del(&shouts); -} diff --git a/examples/csmap_ex2.c b/examples/csmap_ex2.c deleted file mode 100644 index b316d292..00000000 --- a/examples/csmap_ex2.c +++ /dev/null @@ -1,74 +0,0 @@ -#include -#include -#include -#include -#ifdef __cplusplus -#include -#endif - -using_csmap(i, int, int); -enum {N=2000}; -int main() -{ - clock_t t1, t2, t3, t4, t5; - { - t1 = clock(); - csmap_i map = csmap_i_init(); - stc64_srandom(123); - c_forrange (i, 12) { - int x = stc64_random() & 0xff; - csmap_i_emplace(&map, x, i); - printf(" %d", x); - } - puts(""); - c_foreach (i, csmap_i, map) printf(" %d", i.ref->first); - puts("\n"); - //c_foreach (i, csmap_i, map) - //printf("%d: %d\n", i.ref->first, i.ref->second); - printf("size %zu\n", csmap_i_size(map)); - - stc64_srandom(123); - c_forrange (i, 6) { - int x = stc64_random() & 0xff; - printf("Try erase: %d\n", x); - csmap_i_erase(&map, x); - c_foreach (i, csmap_i, map) printf(" %d", i.ref->first); - puts(""); - } - t2 = clock(); - size_t n = 0, sum = 0; - c_foreach (i, csmap_i, map) - sum += i.ref->first; - t3 = clock(); - //c_foreach (i, csmap_i, map) - //if (n++ < 20) printf("%d: %d\n", i.ref->first, i.ref->second); else break; - printf("size %zu: %zu\n", csmap_i_size(map), sum); - - t4 = clock(); - csmap_i_del(&map); - } - t5 = clock(); - printf("emplace: %g sec, sum: %g sec, destruct: %g sec\n", (float)(t2-t1)/CLOCKS_PER_SEC, (float)(t3-t2)/CLOCKS_PER_SEC, (float)(t5-t4)/CLOCKS_PER_SEC); -#ifdef __cplusplus - { - t1 = clock(); - std::map map; - stc64_srandom(1); - c_forrange (i, N) - map.emplace(stc64_random() & 0xffffff, i); - c_forrange (i, N/2) - map.erase(stc64_random() & 0xffffff); - t2 = clock(); - size_t n = 0, sum = 0; - for (auto i: map) - sum += i.first; - t3 = clock(); - for (auto i: map) - if (n++ < 20) printf("%d: %d\n", i.first, i.second); else break; - printf("size %zu: %zu\n", map.size(), sum); - t4 = clock(); - } - t5 = clock(); - printf("emplace %g sec, sum: %g sec, destruct: %g sec\n", (float)(t2-t1)/CLOCKS_PER_SEC, (float)(t3-t2)/CLOCKS_PER_SEC, (float)(t5-t4)/CLOCKS_PER_SEC); -#endif -} \ No newline at end of file diff --git a/examples/ptr.c b/examples/ptr.c deleted file mode 100644 index 98fe0811..00000000 --- a/examples/ptr.c +++ /dev/null @@ -1,80 +0,0 @@ -#include -#include -#include - -typedef struct { cstr_t name, last; } 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; -} -void Person_del(Person* p) { - printf("del: %s\n", p->name.str); - c_del(cstr, &p->name, &p->last); -} -Person Person_clone(Person p) { - p.name = cstr_clone(p.name); - p.last = cstr_clone(p.last); - return p; -} - -// 1. cvec of Person struct -using_cvec(pe, Person, Person_compare, Person_del, Person_clone); - -// 2. cvec of raw/owned pointers to Person -using_cptr(pe, Person, Person_compare, Person_del, Person_clone); -using_cvec(pp, Person*, cptr_pe_compare, cptr_pe_del, cptr_pe_clone); - -// 3. cvec of shared-ptr to Person -using_csptr(pe, Person, Person_compare, Person_del); -using_cvec(ps, csptr_pe, csptr_pe_compare, csptr_pe_del, csptr_pe_clone); - -const char* names[] = { - "Joe", "Jordan", - "Annie", "Aniston", - "Jane", "Jacobs" -}; - -int main() { - cvec_pe vec1 = cvec_pe_init(); - cvec_pp vec2 = cvec_pp_init(); - cvec_ps vec3 = cvec_ps_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_pp_push_back(&vec2, Person_make(c_new(Person), names[i], names[i+1])); - cvec_ps_push_back(&vec3, csptr_pe_from(Person_make(c_new(Person), names[i], names[i+1]))); - } - puts("1. sorted cvec of Person :"); - cvec_pe_sort(&vec1); - c_foreach (i, cvec_pe, vec1) - printf(" %s %s\n", i.ref->name.str, i.ref->last.str); - - puts("\n2. sorted cvec of pointer to Person :"); - cvec_pp_sort(&vec2); - c_foreach (i, cvec_pp, vec2) - printf(" %s %s\n", (*i.ref)->name.str, (*i.ref)->last.str); - - puts("\n3. sorted cvec of shared-pointer to Person :"); - cvec_ps_sort(&vec3); - c_foreach (i, cvec_ps, vec3) - printf(" %s %s\n", i.ref->get->name.str, i.ref->get->last.str); - - // share vec3[1] with elem variable. - csptr_pe elem = csptr_pe_clone(vec3.data[1]); - - puts("\nDestroy vec3:"); - cvec_ps_del(&vec3); // destroys all elements, but elem! - puts("\nDestroy vec2:"); - cvec_pp_del(&vec2); - puts("\nDestroy vec1:"); - cvec_pe_del(&vec1); - - puts("\nDestroy elem:"); - csptr_pe_del(&elem); -} \ No newline at end of file diff --git a/stc/cptr.h b/stc/cptr.h index 4a2a4b87..303a9e66 100644 --- a/stc/cptr.h +++ b/stc/cptr.h @@ -44,13 +44,13 @@ int Person_compare(const Person* p, const Person* q) { return cmp == 0 ? strcmp(p->last.str, q->last.str) : cmp; } -using_cptr(pe, Person, Person_del, Person_compare); -using_cvec(pe, Person*, cptr_pe_del, cptr_pe_compare); +using_cptr(pe, Person, Person_compare, Person_del, c_no_clone); +using_cvec(pe, Person*, cptr_pe_compare, cptr_pe_del, c_no_clone); int main() { cvec_pe vec = cvec_pe_init(); - cvec_pe_push_back(&vec, Person_make(c_new(Person), "Joe", "Jordan")); - cvec_pe_push_back(&vec, Person_make(c_new(Person), "Jane", "Jacobs")); + cvec_pe_push_back(&vec, Person_make(c_new(Person), "John", "Smiths")); + cvec_pe_push_back(&vec, Person_make(c_new(Person), "Jane", "Doe")); c_foreach (i, cvec_pe, vec) printf("%s %s\n", (*i.ref)->name.str, (*i.ref)->last.str); @@ -113,13 +113,13 @@ void Person_del(Person* p) { c_del(cstr, &p->name, &p->last); } -using_csptr(pe, Person, Person_del); +using_csptr(pe, Person, c_no_compare, Person_del); int main() { - csptr_pe p = csptr_pe_make(Person_make(c_new(Person), "Joe", "Jordan")); + csptr_pe p = csptr_pe_from(Person_make(c_new(Person), "John", "Smiths")); csptr_pe q = csptr_pe_clone(p); // share the pointer - printf("%s %s: %d\n", q.get->name.str, q.get->last.str, *q.use_count); + printf("%s %s. uses: %zu\n", q.get->name.str, q.get->last.str, *q.use_count); c_del(csptr_pe, &p, &q); } */ @@ -162,9 +162,6 @@ typedef long atomic_count_t; #define using_csptr_3(X, Value, valueCompare) \ using_csptr_4(X, Value, valueCompare, c_default_del) -#define using_csptr_5(X, Value, valueCompare, valueDestroy, dummyValueClone) \ - using_csptr_4(X, Value, valueCompare, valueDestroy) - #define using_csptr_4(X, Value, valueCompare, valueDestroy) \ typedef Value csptr_##X##_value_t; \ typedef struct { csptr_##X##_value_t* get; atomic_count_t* use_count; } csptr_##X; \ -- cgit v1.2.3