From 6285483b31055a4869a104aba54622e9030448d8 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Tue, 28 Sep 2021 12:58:04 +0200 Subject: Added c_apply_n() and c_apply_pair_n() macros. Rewrote cpque.c example. --- docs/ccommon_api.md | 7 ++++- examples/cpque.c | 72 ++++++++++++++++++++++----------------------------- examples/new_sptr.c | 2 +- examples/sharedptr.c | 2 +- examples/sptr_ex.c | 4 +-- include/stc/ccommon.h | 16 +++++++++--- 6 files changed, 54 insertions(+), 49 deletions(-) diff --git a/docs/ccommon_api.md b/docs/ccommon_api.md index 8e8cbb28..5f31e572 100644 --- a/docs/ccommon_api.md +++ b/docs/ccommon_api.md @@ -125,8 +125,13 @@ c_forrange (i, int, 30, 0, -5) printf(" %d", i); ### c_apply, c_apply_pair **c_apply** will apply a method on an existing container with the given array elements: ```c -c_apply (cvec_i, push_back, &vec, {1, 2, 3}); // apply multiple push_backs +c_apply(cvec_i, push_back, &vec, {1, 2, 3}); // apply multiple push_backs c_apply_pair(cmap_i, insert, &map, { {4, 5}, {6, 7} }); // inserts to existing map + +int arr[] = {1, 2, 3}; +cmap_i_value_t arr2[] = { {4, 5}, {6, 7} }; +c_apply_n(cvec_i, push_back, &vec, arr, c_arraylen(arr)); +c_apply_pair_n(cmap_i, insert, &map, arr2, c_arraylen(arr2)); ``` ### c_new, c_new_n, c_del, c_make diff --git a/examples/cpque.c b/examples/cpque.c index 17447341..eabf11d0 100644 --- a/examples/cpque.c +++ b/examples/cpque.c @@ -1,56 +1,46 @@ // Implements c++ example: https://en.cppreference.com/w/cpp/container/priority_queue #include +#include -#define i_tag imax -#define i_val int -#include +// Example of dynamic compare function -#define i_tag imin -#define i_val int -#define i_cmp -c_default_compare -#include +static int (*icmp_fn)(const int* x, const int* y); -#define imix_less(x, y) ((*(x) ^ 1) < (*(y) ^ 1)) -#define i_tag imix #define i_val int -#define i_cmp(x, y) c_less_compare(imix_less, x, y) +#define i_cnt ipque +#define i_cmp icmp_fn #include -#define PRINT_Q(Q) \ - void print_##Q(Q q) { \ - Q copy = Q##_clone(q); \ - while (!Q##_empty(copy)) { \ - printf("%d ", *Q##_top(©)); \ - Q##_pop(©); \ - } \ - puts(""); \ - Q##_del(©); \ +#define imix_less(x, y) ((*(x) ^ 1) < (*(y) ^ 1)) +static int imax_cmp(const int* x, const int* y) { return *x - *y; } +static int imin_cmp(const int* x, const int* y) { return *y - *x; } +static int imix_cmp(const int* x, const int* y) { return c_less_compare(imix_less, x, y); } + +void print_pque(ipque q) { + ipque copy = ipque_clone(q); + while (!ipque_empty(copy)) { + printf("%d ", *ipque_top(©)); + ipque_pop(©); } - -PRINT_Q(cpque_imin) -PRINT_Q(cpque_imax) -PRINT_Q(cpque_imix) - + puts(""); + ipque_del(©); +} int main() { - const int data[] = {1,8,5,6,3,4,0,9,7,2}; - - c_auto (cpque_imax, q) // init() and defered del() - c_auto (cpque_imin, q2) - c_auto (cpque_imix, q3) + const int data[] = {1,8,5,6,3,4,0,9,7,2}, n = c_arraylen(data); + c_auto (ipque, q, q2, q3) // init() and defered del() { - c_forrange (n, c_arraylen(data)) - cpque_imax_push(&q, n); - print_cpque_imax(q); - - c_forrange (i, c_arraylen(data)) - cpque_imin_push(&q2, data[i]); - print_cpque_imin(q2); - - // Using imix_less to compare elements. - c_forrange (n, c_arraylen(data)) - cpque_imix_push(&q3, n); - print_cpque_imix(q3); + icmp_fn = imax_cmp; + c_apply_n(ipque, push, &q, data, n); + print_pque(q); + + icmp_fn = imin_cmp; + c_apply_n(ipque, push, &q2, data, n); + print_pque(q2); + + icmp_fn = imix_cmp; + c_apply_n(ipque, push, &q3, data, n); + print_pque(q3); } } \ No newline at end of file diff --git a/examples/new_sptr.c b/examples/new_sptr.c index be70e00c..002f6ade 100644 --- a/examples/new_sptr.c +++ b/examples/new_sptr.c @@ -30,7 +30,7 @@ int main(void) { c_autovar (csptr_person p = csptr_person_make(Person_init("John", "Smiths")), csptr_person_del(&p)) c_autovar (csptr_person q = csptr_person_clone(p), csptr_person_del(&q)) // share the pointer { - printf("%s %s. uses: %zu\n", q.get->name.str, q.get->last.str, *q.use_count); + printf("%s %s. uses: %u\n", q.get->name.str, q.get->last.str, *q.use_count); } c_auto (csset_iptr, map) { diff --git a/examples/sharedptr.c b/examples/sharedptr.c index f1861929..e684b9a2 100644 --- a/examples/sharedptr.c +++ b/examples/sharedptr.c @@ -45,7 +45,7 @@ int main() c_foreach (i, csset_int, set) printf(" %d", *i.ref->get); c_autovar (csptr_int p = csptr_int_clone(vec.data[0]), csptr_int_del(&p)) { - printf("\n%d is now owned by %zu objects\n", *p.get, *p.use_count); + printf("\n%d is now owned by %u objects\n", *p.get, *p.use_count); } puts("Done"); diff --git a/examples/sptr_ex.c b/examples/sptr_ex.c index 290833ff..2464ed79 100644 --- a/examples/sptr_ex.c +++ b/examples/sptr_ex.c @@ -53,8 +53,8 @@ void example3() cvec_song_push_back(&v2, csptr_song_make(Song_from("Pink Floyd", "Dogs"))); c_foreach (s, cvec_song, v2) - printf("%s - %s: refs %zu\n", s.ref->get->artist.str, s.ref->get->title.str, - *s.ref->use_count); + printf("%s - %s: refs %u\n", s.ref->get->artist.str, s.ref->get->title.str, + *s.ref->use_count); } } diff --git a/include/stc/ccommon.h b/include/stc/ccommon.h index 919194a8..af56f43a 100644 --- a/include/stc/ccommon.h +++ b/include/stc/ccommon.h @@ -158,18 +158,28 @@ STC_API uint64_t c_default_hash(const void *key, size_t len); #define c_apply(CX, method, cx, ...) do { \ const CX##_rawvalue_t _c_arr[] = __VA_ARGS__; \ - CX* _c_cx = (cx); \ + CX* _c_cx = cx; \ for (size_t _c_i = 0; _c_i < c_arraylen(_c_arr); ++_c_i) \ CX##_##method(_c_cx, _c_arr[_c_i]); \ } while (0) - #define c_apply_pair(CX, method, cx, ...) do { \ const CX##_rawvalue_t _c_arr[] = __VA_ARGS__; \ - CX* _c_cx = (cx); \ + CX* _c_cx = cx; \ for (size_t _c_i = 0; _c_i < c_arraylen(_c_arr); ++_c_i) \ CX##_##method(_c_cx, _c_arr[_c_i].first, _c_arr[_c_i].second); \ } while (0) +#define c_apply_n(CX, method, cx, arr, n) do { \ + CX* _c_cx = cx; \ + for (const CX##_rawvalue_t *_c_i = arr, *_c_end = _c_i+(n); _c_i != _c_end; ++_c_i) \ + CX##_##method(_c_cx, *_c_i); \ +} while (0) +#define c_apply_pair_n(CX, method, cx, arr, n) do { \ + CX* _c_cx = cx; \ + for (const CX##_rawvalue_t *_c_i = arr, *_c_end = _c_i+(n); _c_i != _c_end; ++_c_i) \ + CX##_##method(_c_cx, _c_i->first, _c_i->second); \ +} while (0) + #define c_del(CX, ...) do { \ CX* _c_arr[] = {__VA_ARGS__}; \ for (size_t _c_i = 0; _c_i < c_arraylen(_c_arr); ++_c_i) \ -- cgit v1.2.3