Files
mlib/example/ex-rbtree01.c
T

157 lines
3.5 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include "m-rbtree.h"
// Let's define one utility function.
void *xmalloc(size_t n);
void *xmalloc(size_t n)
{
void *p = malloc (n);
if (!p) abort();
return p;
}
// Let's define a new type.
typedef struct {
int key;
char *data;
} my_type_t[1];
#define SIZE 256
// Let's define the prototypes of the methods of this new type.
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);
// 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(rbtree_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);
}