diff options
| author | _Tradam <[email protected]> | 2023-09-08 01:29:47 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-09-08 01:29:47 +0000 |
| commit | 3c76c7f3d5db3f9586a90d03f8fbb02d79de9acd (patch) | |
| tree | afbe4b540967223911f7c5de36559b82154f02f3 /misc/examples/smartpointers | |
| parent | 0841165881871ee01b782129be681209aeed2423 (diff) | |
| parent | 1a72205fe05c2375cfd380dd8381a8460d9ed8d1 (diff) | |
| download | STC-modified-3c76c7f3d5db3f9586a90d03f8fbb02d79de9acd.tar.gz STC-modified-3c76c7f3d5db3f9586a90d03f8fbb02d79de9acd.zip | |
Diffstat (limited to 'misc/examples/smartpointers')
| -rw-r--r-- | misc/examples/smartpointers/arc_containers.c | 80 | ||||
| -rw-r--r-- | misc/examples/smartpointers/arc_demo.c | 63 | ||||
| -rw-r--r-- | misc/examples/smartpointers/arcvec_erase.c | 52 | ||||
| -rw-r--r-- | misc/examples/smartpointers/box.c | 70 | ||||
| -rw-r--r-- | misc/examples/smartpointers/box2.c | 81 | ||||
| -rw-r--r-- | misc/examples/smartpointers/map_box.c | 34 | ||||
| -rw-r--r-- | misc/examples/smartpointers/map_ptr.c | 34 | ||||
| -rw-r--r-- | misc/examples/smartpointers/music_arc.c | 67 | ||||
| -rw-r--r-- | misc/examples/smartpointers/new_sptr.c | 76 | ||||
| -rw-r--r-- | misc/examples/smartpointers/person_arc.c | 78 |
10 files changed, 635 insertions, 0 deletions
diff --git a/misc/examples/smartpointers/arc_containers.c b/misc/examples/smartpointers/arc_containers.c new file mode 100644 index 00000000..79211d2b --- /dev/null +++ b/misc/examples/smartpointers/arc_containers.c @@ -0,0 +1,80 @@ +// Create a stack and a list of shared pointers to maps, +// and demonstrate sharing and cloning of maps. +#define i_implement +#include <stc/cstr.h> +#define i_type Map +#define i_key_str // strings +#define i_val int +#define i_keydrop(p) (printf("drop name: %s\n", cstr_str(p)), cstr_drop(p)) +#include <stc/csmap.h> + +#define i_type Arc // (atomic) ref. counted type +#define i_key Map +#define i_keydrop(p) (printf("drop Arc:\n"), Map_drop(p)) +// no need for atomic ref. count in single thread: +#define i_opt c_no_atomic +#include <stc/carc.h> + +#define i_type Stack +#define i_keyboxed Arc // use i_keyboxed for carc/cbox key +#include <stc/cvec.h> + +#define i_type List +#define i_keyboxed Arc // as above +#include <stc/clist.h> + +int main(void) +{ + Stack stack = {0}; + List list = {0}; + c_defer( + Stack_drop(&stack), + List_drop(&list) + ){ + // POPULATE stack with shared pointers to Maps: + Map *map; + map = Stack_push(&stack, Arc_from(Map_init()))->get; + Map_emplace(map, "Joey", 1990); + Map_emplace(map, "Mary", 1995); + Map_emplace(map, "Joanna", 1992); + + map = Stack_push(&stack, Arc_from(Map_init()))->get; + Map_emplace(map, "Rosanna", 2001); + Map_emplace(map, "Brad", 1999); + Map_emplace(map, "Jack", 1980); + + // POPULATE list: + map = List_push_back(&list, Arc_from(Map_init()))->get; + Map_emplace(map, "Steve", 1979); + Map_emplace(map, "Rick", 1974); + Map_emplace(map, "Tracy", 2003); + + // Share two Maps from the stack with the list using emplace (clone the carc): + List_push_back(&list, Arc_clone(stack.data[0])); + List_push_back(&list, Arc_clone(stack.data[1])); + + // Clone (deep copy) a Map from the stack to the list + // List will contain two shared and two unshared maps. + map = List_push_back(&list, Arc_from(Map_clone(*stack.data[1].get)))->get; + + // Add one more element to the cloned map: + Map_emplace_or_assign(map, "CLONED", 2021); + + // Add one more element to the shared map: + Map_emplace_or_assign(stack.data[1].get, "SHARED", 2021); + + puts("STACKS"); + c_foreach (i, Stack, stack) { + c_forpair (name, year, Map, *i.ref->get) + printf(" %s:%d", cstr_str(_.name), *_.year); + puts(""); + } + + puts("LIST"); + c_foreach (i, List, list) { + c_forpair (name, year, Map, *i.ref->get) + printf(" %s:%d", cstr_str(_.name), *_.year); + puts(""); + } + } +} diff --git a/misc/examples/smartpointers/arc_demo.c b/misc/examples/smartpointers/arc_demo.c new file mode 100644 index 00000000..a66d84b0 --- /dev/null +++ b/misc/examples/smartpointers/arc_demo.c @@ -0,0 +1,63 @@ +#include <stdio.h> +#include <string.h> + +void int_drop(int* x) { + printf("drop: %d\n", *x); +} + +// carc implements its own clone method using reference counting, +// so 'i_keyclone' is not required to be defined (ignored). + +#define i_type Arc // set type name to be defined (instead of 'carc_int') +#define i_key int +#define i_keydrop int_drop // optional, just to display the elements destroyed +#define i_use_cmp // use int comparison (x < y, x == y). +#include <stc/carc.h> // Arc + +#define i_keyboxed Arc // note: use i_keyboxed instead of i_key for carc/cbox elements +#include <stc/csset.h> // csset_Arc (like: std::set<std::shared_ptr<int>>) + +#define i_keyboxed Arc // note: as above. +#define i_use_cmp +#include <stc/cvec.h> // cvec_Arc (like: std::vector<std::shared_ptr<int>>) + +int main(void) +{ + const int years[] = {2021, 2012, 2022, 2015}; + + cvec_Arc vec = {0}; + c_forrange (i, c_arraylen(years)) { + cvec_Arc_emplace(&vec, years[i]); + // cvec_Arc_push(&vec, Arc_from(years[i])); // alt. + } + + cvec_Arc_sort(&vec); + + printf("vec:"); + c_foreach (i, cvec_Arc, vec) + printf(" %d", *i.ref->get); + puts(""); + + // add odd numbers from vec to set + csset_Arc set = {0}; + c_foreach (i, cvec_Arc, vec) + if (*i.ref->get & 1) + csset_Arc_insert(&set, Arc_clone(*i.ref)); // copy shared pointer => increments counter. + + // erase the two last elements in vec + cvec_Arc_pop_back(&vec); + cvec_Arc_pop_back(&vec); + + printf("vec:"); + c_foreach (i, cvec_Arc, vec) printf(" %d", *i.ref->get); + + printf("\nset:"); + c_foreach (i, csset_Arc, set) printf(" %d", *i.ref->get); + + Arc p = Arc_clone(vec.data[0]); + printf("\n%d is now owned by %ld objects\n", *p.get, *p.use_count); + + Arc_drop(&p); + cvec_Arc_drop(&vec); + csset_Arc_drop(&set); +} diff --git a/misc/examples/smartpointers/arcvec_erase.c b/misc/examples/smartpointers/arcvec_erase.c new file mode 100644 index 00000000..0526b6a0 --- /dev/null +++ b/misc/examples/smartpointers/arcvec_erase.c @@ -0,0 +1,52 @@ +#include <stdio.h> + +void show_drop(int* x) { printf("drop: %d\n", *x); } + +#define i_type Arc +#define i_key int +#define i_keydrop show_drop +#define i_use_cmp // enable sort/search for int type +#include <stc/carc.h> // Shared pointer to int + +#define i_type Vec +#define i_keyboxed Arc +#define i_use_cmp +#include <stc/cvec.h> // Vec: cvec<Arc> + + +int main(void) +{ + Vec vec = c_init(Vec, {2012, 1990, 2012, 2019, 2015}); + + // clone the second 2012 and push it back. + // note: cloning make sure that vec.data[2] has ref count 2. + Vec_push(&vec, Arc_clone(vec.data[2])); // => share vec.data[2] + Vec_emplace(&vec, *vec.data[2].get); // => deep-copy vec.data[2] + + printf("vec before erase :"); + c_foreach (i, Vec, vec) + printf(" %d", *i.ref->get); + + printf("\nerase vec.data[2]; or first matching value depending on compare.\n"); + Vec_iter it; + it = Vec_find(&vec, *vec.data[2].get); + if (it.ref) + Vec_erase_at(&vec, it); + + int year = 2015; + it = Vec_find(&vec, year); // Ok as tmp only. + if (it.ref) + Vec_erase_at(&vec, it); + + printf("vec after erase :"); + c_foreach (i, Vec, vec) + printf(" %d", *i.ref->get); + + Vec_sort(&vec); + printf("\nvec after sort :"); + c_foreach (i, Vec, vec) + printf(" %d", *i.ref->get); + + puts("\nDone"); + Vec_drop(&vec); +} diff --git a/misc/examples/smartpointers/box.c b/misc/examples/smartpointers/box.c new file mode 100644 index 00000000..5c8018d4 --- /dev/null +++ b/misc/examples/smartpointers/box.c @@ -0,0 +1,70 @@ +/* cbox: heap allocated boxed type */ +#define i_implement +#include <stc/cstr.h> + +typedef struct { cstr name, last; } Person; + +Person Person_make(const char* name, const char* last) { + return c_LITERAL(Person){.name = cstr_from(name), .last = cstr_from(last)}; +} + +uint64_t Person_hash(const Person* a) { + return cstr_hash(&a->name) ^ cstr_hash(&a->last); +} + +int Person_cmp(const Person* a, const Person* b) { + int c = cstr_cmp(&a->name, &b->name); + return c ? c : cstr_cmp(&a->last, &b->last); +} + +Person Person_clone(Person p) { + p.name = cstr_clone(p.name); + p.last = cstr_clone(p.last); + return p; +} + +void Person_drop(Person* p) { + printf("drop: %s %s\n", cstr_str(&p->name), cstr_str(&p->last)); + c_drop(cstr, &p->name, &p->last); +} + +#define i_type PBox +#define i_keyclass Person // "class" binds _cmp, _clone, _drop functions. +#define i_use_cmp +#include <stc/cbox.h> + +#define i_type Persons +#define i_keyboxed PBox // "arcbox" informs that PBox is a smart pointer. +#include <stc/csset.h> + +int main(void) +{ + Persons vec = {0}; + PBox p = PBox_from(Person_make("Laura", "Palmer")); + PBox q = PBox_clone(p); + cstr_assign(&q.get->name, "Leland"); + + printf("orig: %s %s\n", cstr_str(&p.get->name), cstr_str(&p.get->last)); + printf("copy: %s %s\n", cstr_str(&q.get->name), cstr_str(&q.get->last)); + + Persons_emplace(&vec, Person_make("Dale", "Cooper")); + Persons_emplace(&vec, Person_make("Audrey", "Home")); + + // NB! Clone/share p and q in the Persons container. + Persons_push(&vec, PBox_clone(p)); + Persons_push(&vec, PBox_clone(q)); + + c_foreach (i, Persons, vec) + printf("%s %s\n", cstr_str(&i.ref->get->name), cstr_str(&i.ref->get->last)); + puts(""); + + // Look-up Audrey! Create a temporary Person for lookup. + Person a = Person_make("Audrey", "Home"); + const PBox *v = Persons_get(&vec, a); // lookup + if (v) printf("found: %s %s\n", cstr_str(&v->get->name), cstr_str(&v->get->last)); + + Person_drop(&a); + PBox_drop(&p); + PBox_drop(&q); + Persons_drop(&vec); +} diff --git a/misc/examples/smartpointers/box2.c b/misc/examples/smartpointers/box2.c new file mode 100644 index 00000000..9b782c74 --- /dev/null +++ b/misc/examples/smartpointers/box2.c @@ -0,0 +1,81 @@ +// example: https://doc.rust-lang.org/rust-by-example/std/box.html +#include <stdio.h> + +typedef struct { + double x; + double y; +} Point; + +// A Rectangle can be specified by where its top left and bottom right +// corners are in space +typedef struct { + Point top_left; + Point bottom_right; +} Rectangle; + +#define i_key Point +#include <stc/cbox.h> // cbox_Point + +#define i_key Rectangle +#include <stc/cbox.h> // cbox_Rectangle + +// Box in box: +#define i_type BoxBoxPoint +#define i_keyboxed cbox_Point // NB: use i_keyboxed when value is a cbox or carc! +#include <stc/cbox.h> // BoxBoxPoint + +Point origin(void) { + return c_LITERAL(Point){ .x=1.0, .y=2.0 }; +} + +cbox_Point boxed_origin(void) { + // Allocate this point on the heap, and return a pointer to it + return cbox_Point_make(c_LITERAL(Point){ .x=1.0, .y=2.0 }); +} + + +int main(void) { + // Stack allocated variables + Point point = origin(); + Rectangle rectangle = { + .top_left = origin(), + .bottom_right = { .x=3.0, .y=-4.0 } + }; + + // Heap allocated rectangle + cbox_Rectangle boxed_rectangle = cbox_Rectangle_make(c_LITERAL(Rectangle){ + .top_left = origin(), + .bottom_right = { .x=3.0, .y=-4.0 } + }); + // The output of functions can be boxed + cbox_Point boxed_point = cbox_Point_make(origin()); + + // Can use from(raw) and toraw instead: + BoxBoxPoint box_in_a_box = BoxBoxPoint_from(origin()); + + c_defer( + BoxBoxPoint_drop(&box_in_a_box), + cbox_Point_drop(&boxed_point), + cbox_Rectangle_drop(&boxed_rectangle) + ){ + printf("box_in_a_box: x = %g\n", BoxBoxPoint_toraw(&box_in_a_box).x); + + printf("Point occupies %d bytes on the stack\n", + (int)sizeof(point)); + printf("Rectangle occupies %d bytes on the stack\n", + (int)sizeof(rectangle)); + + // box size == pointer size + printf("Boxed point occupies %d bytes on the stack\n", + (int)sizeof(boxed_point)); + printf("Boxed rectangle occupies %d bytes on the stack\n", + (int)sizeof(boxed_rectangle)); + printf("Boxed box occupies %d bytes on the stack\n", + (int)sizeof(box_in_a_box)); + + // Copy the data contained in `boxed_point` into `unboxed_point` + Point unboxed_point = *boxed_point.get; + printf("Unboxed point occupies %d bytes on the stack\n", + (int)sizeof(unboxed_point)); + } +} diff --git a/misc/examples/smartpointers/map_box.c b/misc/examples/smartpointers/map_box.c new file mode 100644 index 00000000..f651b302 --- /dev/null +++ b/misc/examples/smartpointers/map_box.c @@ -0,0 +1,34 @@ +#include <stc/ccommon.h> +#include <stdio.h> +#define i_implement +#include <stc/cstr.h> + +#define i_type IBox +#define i_key long +#include <stc/cbox.h> // unique_ptr<long> alike. + +// cmap of cstr => IBox +#define i_type Boxmap +#define i_key_str +#define i_valboxed IBox // i_valboxed: use properties from IBox automatically +#include <stc/cmap.h> + + +int main(void) +{ + Boxmap map = {0}; + + puts("Map cstr => IBox:"); + Boxmap_insert(&map, cstr_from("Test1"), IBox_make(1)); + Boxmap_insert(&map, cstr_from("Test2"), IBox_make(2)); + + // Simpler: emplace() implicitly creates cstr from const char* and IBox from long! + Boxmap_emplace(&map, "Test3", 3); + Boxmap_emplace(&map, "Test4", 4); + + c_forpair (name, number, Boxmap, map) + printf("%s: %ld\n", cstr_str(_.name), *_.number->get); + puts(""); + + Boxmap_drop(&map); +} diff --git a/misc/examples/smartpointers/map_ptr.c b/misc/examples/smartpointers/map_ptr.c new file mode 100644 index 00000000..453322c5 --- /dev/null +++ b/misc/examples/smartpointers/map_ptr.c @@ -0,0 +1,34 @@ +#include <stc/ccommon.h> +#include <stdio.h> +#define i_implement +#include <stc/cstr.h> + +// cmap of cstr => long* +#define i_type Ptrmap +#define i_key_str +#define i_val long* +#define i_valraw long +#define i_valfrom(raw) c_new(long, raw) +#define i_valto(x) **x +#define i_valclone(x) c_new(long, *x) +#define i_valdrop(x) c_free(*x) +#include <stc/cmap.h> + +int main(void) +{ + Ptrmap map = {0}; + + puts("Map cstr => long*:"); + Ptrmap_insert(&map, cstr_from("Test1"), c_new(long, 1)); + Ptrmap_insert(&map, cstr_from("Test2"), c_new(long, 2)); + + // Simple: emplace() implicitly creates cstr from const char* and an owned long* from long! + Ptrmap_emplace(&map, "Test3", 3); + Ptrmap_emplace(&map, "Test4", 4); + + c_forpair (name, number, Ptrmap, map) + printf("%s: %ld\n", cstr_str(_.name), **_.number); + puts(""); + + Ptrmap_drop(&map); +} diff --git a/misc/examples/smartpointers/music_arc.c b/misc/examples/smartpointers/music_arc.c new file mode 100644 index 00000000..e9ebbbfe --- /dev/null +++ b/misc/examples/smartpointers/music_arc.c @@ -0,0 +1,67 @@ +// shared_ptr-examples.cpp +// based on https://docs.microsoft.com/en-us/cpp/cpp/how-to-create-and-use-shared-ptr-instances?view=msvc-160 +#define i_implement +#include <stc/cstr.h> + +typedef struct +{ + cstr artist; + cstr title; +} Song; + +int Song_cmp(const Song* x, const Song* y) + { return cstr_cmp(&x->title, &y->title); } + +Song Song_init(const char* artist, const char* title) + { return c_LITERAL(Song){cstr_from(artist), cstr_from(title)}; } + +void Song_drop(Song* s) { + printf("drop: %s\n", cstr_str(&s->title)); + c_drop(cstr, &s->artist, &s->title); +} + +// Define the shared pointer: +#define i_type SongArc +#define i_keyclass Song +#define i_opt c_use_cmp|c_no_hash +#include <stc/carc.h> + +// ... and a vector of them +#define i_type SongVec +#define i_keyboxed SongArc // use i_keyboxed on carc / cbox (instead of i_key) +#include <stc/cvec.h> + +void example3(void) +{ + SongVec vec1 = c_init(SongVec, { + Song_init("Bob Dylan", "The Times They Are A Changing"), + Song_init("Aretha Franklin", "Bridge Over Troubled Water"), + Song_init("Thalia", "Entre El Mar y Una Estrella") + }); + + SongVec vec2 = {0}; + // Share all entries in vec with vec2, except Bob Dylan. + c_foreach (s, SongVec, vec1) + if (!cstr_equals(&s.ref->get->artist, "Bob Dylan")) + SongVec_push(&vec2, SongArc_clone(*s.ref)); + + // Add a few more to vec2. We can use emplace when creating new entries + // Emplace calls SongArc_from() on the argument to create the Arc: + SongVec_emplace(&vec2, Song_init("Michael Jackson", "Billie Jean")); + SongVec_emplace(&vec2, Song_init("Rihanna", "Stay")); + + // We now have two vectors with some shared, some unique entries. + c_forlist (i, SongVec, {vec1, vec2}) { + puts("VEC:"); + c_foreach (s, SongVec, *i.ref) + printf(" %s - %s, REFS: %ld\n", cstr_str(&s.ref->get->artist), + cstr_str(&s.ref->get->title), + *s.ref->use_count); + } + c_drop(SongVec, &vec1, &vec2); +} + +int main(void) +{ + example3(); +}
\ No newline at end of file diff --git a/misc/examples/smartpointers/new_sptr.c b/misc/examples/smartpointers/new_sptr.c new file mode 100644 index 00000000..50e28ae2 --- /dev/null +++ b/misc/examples/smartpointers/new_sptr.c @@ -0,0 +1,76 @@ +#define i_implement +#include <stc/cstr.h> + +typedef struct { cstr name, last; } Person; +Person Person_make(const char* name, const char* last); +Person Person_clone(Person p); +void Person_drop(Person* p); +int Person_cmp(const Person* a, const Person* b); +uint64_t Person_hash(const Person* p); + +#define i_type PersonArc +#define i_keyclass Person // "class" assume _clone, _drop, _cmp, _hash is defined. +#define i_use_cmp +#include <stc/carc.h> + +#define i_type IPtr +#define i_key int +#define i_keydrop(x) printf("drop: %d\n", *x) +#define i_use_cmp +#include <stc/carc.h> + +#define i_type IPStack +#define i_keyboxed IPtr +#include <stc/cstack.h> + +#define i_type PASet +#define i_keyboxed PersonArc +#include <stc/cset.h> + + +Person Person_make(const char* name, const char* last) { + Person p = {.name = cstr_from(name), .last = cstr_from(last)}; + return p; +} + +int Person_cmp(const Person* a, const Person* b) { + return cstr_cmp(&a->name, &b->name); +} + +uint64_t Person_hash(const Person* p) { + return cstr_hash(&p->name); +} + +Person Person_clone(Person p) { + p.name = cstr_clone(p.name), p.last = cstr_clone(p.last); + return p; +} + +void Person_drop(Person* p) { + printf("drop: %s %s\n", cstr_str(&p->name), cstr_str(&p->last)); + c_drop(cstr, &p->name, &p->last); +} + + +int main(void) { + puts("Ex1"); + PersonArc p = PersonArc_from(Person_make("John", "Smiths")); + PersonArc q = PersonArc_clone(p); // share + PersonArc r = PersonArc_clone(p); + PersonArc s = PersonArc_from(Person_clone(*p.get)); // deep copy + printf("%s %s: refs %ld\n", cstr_str(&p.get->name), cstr_str(&p.get->last), *p.use_count); + c_drop(PersonArc, &p, &q, &r, &s); + + puts("Ex2"); + IPStack vec = {0}; + IPStack_push(&vec, IPtr_from(10)); + IPStack_push(&vec, IPtr_from(20)); + IPStack_emplace(&vec, 30); // same as IPStack_push(&vec, IPtr_from(30)); + IPStack_push(&vec, IPtr_clone(*IPStack_back(&vec))); + IPStack_push(&vec, IPtr_clone(*IPStack_front(&vec))); + + c_foreach (i, IPStack, vec) + printf(" (%d: refs %ld)", *i.ref->get, *i.ref->use_count); + puts(""); + IPStack_drop(&vec); +} diff --git a/misc/examples/smartpointers/person_arc.c b/misc/examples/smartpointers/person_arc.c new file mode 100644 index 00000000..11040cd2 --- /dev/null +++ b/misc/examples/smartpointers/person_arc.c @@ -0,0 +1,78 @@ +/* cbox: heap allocated boxed type */ +#define i_implement +#include <stc/cstr.h> + +typedef struct { cstr name, last; } Person; + +Person Person_make(const char* name, const char* last) { + Person p = {.name = cstr_from(name), .last = cstr_from(last)}; + return p; +} + +int Person_cmp(const Person* a, const Person* b) { + int c = cstr_cmp(&a->name, &b->name); + return c ? c : cstr_cmp(&a->last, &b->last); +} + +uint64_t Person_hash(const Person* a) { + return cstr_hash(&a->name) ^ cstr_hash(&a->last); +} + +Person Person_clone(Person p) { + p.name = cstr_clone(p.name); + p.last = cstr_clone(p.last); + return p; +} + +void Person_drop(Person* p) { + printf("drop: %s %s\n", cstr_str(&p->name), cstr_str(&p->last)); + c_drop(cstr, &p->name, &p->last); +} + +#define i_type PSPtr +#define i_keyclass Person // ensure Person_drop +#define i_use_cmp +#include <stc/carc.h> + +#define i_type Persons +#define i_keyboxed PSPtr // binds PSPtr_cmp, PSPtr_drop... +#define i_use_cmp +#include <stc/cvec.h> + + +int main(void) +{ + PSPtr p = PSPtr_from(Person_make("Laura", "Palmer")); + PSPtr q = PSPtr_from(Person_clone(*p.get)); // deep copy + Persons vec = {0}; + + c_defer( + PSPtr_drop(&p), + PSPtr_drop(&q), + Persons_drop(&vec) + ){ + cstr_assign(&q.get->name, "Leland"); + + printf("orig: %s %s\n", cstr_str(&p.get->name), cstr_str(&p.get->last)); + printf("copy: %s %s\n", cstr_str(&q.get->name), cstr_str(&q.get->last)); + + // Use Persons_emplace to implicitly call PSPtr_make on the argument. + // No need to do: Persons_push(&vec, PSPtr_make(Person_make("Audrey", "Home"))); + Persons_emplace(&vec, Person_make("Audrey", "Home")); + Persons_emplace(&vec, Person_make("Dale", "Cooper")); + + // Clone/share p and q to the vector + c_forlist (i, PSPtr, {p, q}) + Persons_push(&vec, PSPtr_clone(*i.ref)); + + c_foreach (i, Persons, vec) + printf("%s %s\n", cstr_str(&i.ref->get->name), cstr_str(&i.ref->get->last)); + puts(""); + + // Look-up Audrey! + Person a = Person_make("Audrey", "Home"); + const PSPtr *v = Persons_get(&vec, a); + if (v) printf("found: %s %s\n", cstr_str(&v->get->name), cstr_str(&v->get->last)); + Person_drop(&a); + } +} |
