diff --git a/example/ex11.c b/example/ex11.c new file mode 100644 index 00000000..d929e2bd --- /dev/null +++ b/example/ex11.c @@ -0,0 +1,154 @@ +#include +#include +#include + +#include "m-rbtree.h" + +// Let's define a new type. +typedef struct { + int key; + char *data; +} my_type_t[1]; + +#define SIZE 256 + +void *xmalloc(size_t n); +void my_type_init(my_type_t x); +void my_type_clear(my_type_t x); +void my_type_init_set(my_type_t x, const my_type_t y); +void my_type_set(my_type_t x, const my_type_t y); +void my_type_init_move(my_type_t x, my_type_t y); +int my_type_cmp(const my_type_t x, const my_type_t y); +size_t my_type_hash(const my_type_t x); +void my_type_out_str(FILE *f, const my_type_t x); +bool my_type_in_str(my_type_t x, FILE *f); +void my_type_rand(my_type_t x); + +void *xmalloc(size_t n) +{ + void *p = malloc (n); + if (!p) abort(); + return p; +} + +// Let's define its constructor +void my_type_init(my_type_t x) +{ + x->key = 0; + x->data = xmalloc (SIZE); +} + +// Let's define its destructor +void my_type_clear(my_type_t x) +{ + free (x->data); +} + +// Let's define its copy constructor +void my_type_init_set(my_type_t x, const my_type_t y) +{ + x->key = y->key; + x->data = xmalloc (SIZE); + memcpy(x->data, y->data, SIZE); +} + +// Let's define its copy method +void my_type_set(my_type_t x, const my_type_t y) +{ + x->key = y->key; + memcpy(x->data, y->data, SIZE); +} + +// Let's define its move constructor +void my_type_init_move(my_type_t x, my_type_t y) +{ + x->key = y->key; + x->data = y->data; +} + +// Let's define its comparison method +int my_type_cmp(const my_type_t x, const my_type_t y) +{ + return (x->key < y->key) ? -1 : (x->key > y->key); +} + +// Let's define its hash method +// (Not needed for tree) +size_t my_type_hash(const my_type_t x) +{ + return m_core_hash(&x->key, sizeof(x->key)); +} + +// Let's define its output method +void my_type_out_str(FILE *f, const my_type_t x) +{ + fprintf (f, "{ key: %d, data: ", x->key); + for(int i = 0; i < SIZE; i++) { + fprintf (f, "%02x", x->data[i]); + } + fprintf(f, "}"); +} + +// Let's define its input method +bool my_type_in_str(my_type_t x, FILE *f) +{ + char buffer[256]; + buffer[0] = 0; + fgets (buffer, 8, f); + if (strcmp (buffer, "{ key: ") != 0) + return false; + if (fscanf (f, "%d", &x->key) != 1) + return false; + fgets (buffer, 9, f); + if (strcmp (buffer, ", data: ") != 0) + return false; + for(int i = 0; i < SIZE; i++) { + fgets (buffer, 3, f); + unsigned int n; + if (fscanf (f, "%02x", &n) != 1) + return false; + x->data[i] = n; + } + fgets (buffer, 2, f); + if (strcmp (buffer, "}") != 0) + return false; + return true; +} + +void my_type_rand(my_type_t x) +{ + x->key = rand(); + for(int i = 0 ; i < SIZE; i ++) { + x->data[i] = rand(); + } +} + +// Let's define its oplist +#define MY_TYPE_OPLIST (TYPE(my_type_t), INIT(my_type_init), CLEAR(my_type_clear), INIT_SET(my_type_init_set), SET(my_type_set), INIT_MOVE(my_type_init_move), CMP(my_type_cmp), HASH(my_type_hash), OUT_STR(my_type_out_str), IN_STR(my_type_in_str)) + +// Let's define a Red Black Tree over this structure +RBTREE_DEF(my_type, my_type_t, MY_TYPE_OPLIST) + +int main(int argc, const char *argv[]) +{ + rbtree_my_type_t tree; + my_type_t x; + int n = (argc >= 2) ? atoi(argv[1]) : 10; + + rbtree_my_type_init(tree); + + // Init the tree with random values + my_type_init(x); + for(int i = 0 ; i < n; i++) { + my_type_rand(x); + rbtree_my_type_push (tree, x); + } + my_type_clear(x); + + // Printf the trees + rbtree_my_type_out_str (stdout, tree); + printf ("\n"); + + // Quit + rbtree_my_type_clear(tree); +}