Question

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'?

Was it helpful?

Solution

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;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top