diff options
| author | Tyge Løvset <[email protected]> | 2022-11-05 20:53:55 +0100 |
|---|---|---|
| committer | Tyge Løvset <[email protected]> | 2022-11-05 20:53:55 +0100 |
| commit | c230e4cd830de22fad2f7085d968d905dadc7418 (patch) | |
| tree | 224173728e5b3bb218148166593e00a59d811119 /examples | |
| parent | f36740ba450c4c677863dd86ec94bba128aad574 (diff) | |
| download | STC-modified-c230e4cd830de22fad2f7085d968d905dadc7418.tar.gz STC-modified-c230e4cd830de22fad2f7085d968d905dadc7418.zip | |
Added possibility to have per container-instance customizable compare/lookup functions (cmp, less, eq, hash) for priority queue and associative containers. Is achived by embedding the container in a struct along with function pointer(s) which can be accessed through the c_container_of() macro. See the updated cpque.c example in the examples folder.
Diffstat (limited to 'examples')
| -rw-r--r-- | examples/cpque.c | 77 |
1 files changed, 52 insertions, 25 deletions
diff --git a/examples/cpque.c b/examples/cpque.c index 5866f17b..502a8c7b 100644 --- a/examples/cpque.c +++ b/examples/cpque.c @@ -1,24 +1,40 @@ // Implements c++ example: https://en.cppreference.com/w/cpp/container/priority_queue +// Example of dynamic compare function + #include <stdio.h> #include <stdbool.h> +#include <stc/forward.h> +#include <stc/views.h> -// Example of dynamic compare function +// predeclare +declare_cpque(ipque, int); -static bool (*less_fn)(const int* x, const int* y); +struct { + ipque Q; + bool (*less)(const int*, const int*); +} typedef IPQueue; -#define i_val int -#define i_less less_fn #define i_type ipque +#define i_val int +#define i_opt c_declared // avoid redeclaring container type +#define i_less_functor(self, x, y) c_container_of(self, IPQueue, Q)->less(x, y) // <== This. #include <stc/cpque.h> -void print_queue(ipque q) { - ipque copy = ipque_clone(q); - while (!ipque_empty(©)) { - printf("%d ", *ipque_top(©)); - ipque_pop(©); - } +#define print(name, q, n) do { \ + printf("%s: \t", name); \ + c_forrange (i, n) printf("%d ", q[i]); \ + puts(""); \ +} while(0) + +void print_queue(const char* name, IPQueue q) { + // NB: make a copy because there is no way to traverse + // priority_queue's content without erasing the queue. + IPQueue copy = {ipque_clone(q.Q), q.less}; + + for (printf("%s: \t", name); !ipque_empty(©.Q); ipque_pop(©.Q)) + printf("%d ", *ipque_top(©.Q)); puts(""); - ipque_drop(©); + ipque_drop(©.Q); } static bool int_less(const int* x, const int* y) { return *x < *y; } @@ -28,18 +44,29 @@ static bool int_lambda(const int* x, const int* y) { return (*x ^ 1) < (*y ^ 1); int main() { 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 drop() - { - less_fn = int_less; - c_forrange (i, n) ipque_push(&q, data[i]); - print_queue(q); - - less_fn = int_greater; - c_forrange (i, n) ipque_push(&q2, data[i]); - print_queue(q2); - - less_fn = int_lambda; - c_forrange (i, n) ipque_push(&q3, data[i]); - print_queue(q3); - } + print("data", data, n); + + IPQueue q1 = {ipque_init(), int_less}; // Max priority queue + + c_forrange (i, n) + ipque_push(&q1.Q, data[i]); + + print_queue("q1", q1); + + // Min priority queue + // std::greater<int> makes the max priority queue act as a min priority queue + IPQueue minq1 = {ipque_init(), int_greater}; + c_forrange (i, n) ipque_push(&minq1.Q, data[i]); + + print_queue("minq1", minq1); + + // Using lambda to compare elements. + IPQueue q5 = {ipque_init(), int_lambda}; + + c_forrange (i, n) + ipque_push(&q5.Q, data[i]); + + print_queue("q5", q5); + + c_drop(ipque, &q1.Q, &minq1.Q, &q5.Q); } |
