I am currently building a personal library of data structures, and I realized that they may be able to be abstracted completely by have the data in it be a void *. So let's say that I create a linked list
typedef struct node_ll {
void *data;
struct node_ll *next;
} node_ll;
and let's say that I am creating a linked list of structs where they are defined as
struct person {
char *name;
int age;
};
Then, is it possible to define an abstract search method
void *traverse(void *head, void* data) {}
to find a person who is age 19 and has the name 'John'?
To make your list data structure abstract, simply hide the definition of the node_ll
structure in a source file. The header file would only contain the forward declaration, and the prototypes for the APIs:
typedef struct node_ll node_ll;
typedef struct linkedlist { node_ll *head; } linkedlist;
static inline linkedlist make_linkedlist () {
const linkedlist zero_ll = { 0 };
return zero_ll;
}
void unmake_linkedlist (linkedlist *list);
void linkedlist_add (linkedlist *list, void *data);
void linkedlist_traverse_until (linkedlist *list,
int (*visit)(void *visit_data, void *data),
void *visit_data);
The linkedlist_traverse_until()
function will basically call the provided visit()
function on each node, unless visit()
returns 0, at which point it stops. The implementation of the function knows how to access a node_ll
because it is in the source file that has the complete definition of the struct node_ll
.
while (node) {
if (visit(visit_data, node->data)) {
node = node->next;
continue;
}
break;
}