TreeTree
TreeTree

Reputation: 3230

C Generic ADT with function pointers

I'm writing a generic list adt and this is what I have in the header so far. From what I know this is usually how it's done.

typedef struct _node {
    void *data;
    struct _node *next;
} Node;

typedef struct {
    Node *dummy;
    int (*comparePtr) (void *d1, void *d2);
    void (*destroyPtr) (void *data);
} List;

List *ListCreate (int (*comparePtr) (void *d1, void *d2), void (*destroyPtr) (void *data));
void ListDestroy (List *node);
void ListAddToTail (List *list, void *data);
int ListContains (List *list, void *data);
void *ListGetFromIndex (List *list, int index);

It works fine on the implementation side. What I noticed is that in order to use this adt to store integers I have to make calls in this fashion

int a = 5;
ListAddToTail (list, &a);

whereas in a perfect world I'd be able to do this

ListAddToTail (list, 55);

So the question is is it possible to modify this to allow me to pass in any type of data, pointer or non-pointer, non-pointer being mainly primitive types like integers and characters?

Upvotes: 1

Views: 2622

Answers (1)

cnicutar
cnicutar

Reputation: 182629

There's no clean, completely nice way to solve this. You have a few options:

  • On most platforms you can simply get away with stuffing an integer in a void *. It's messy but it works pretty well, especially if you silence the warnings

  • Define your own boxing functions / macros that allocate the required space and give you back a pointer. You can probably make a really nice macro using typeof tricks. But then you have to remember to free that space

The main issue should be uniformity. Your list lets people store pointers. You should let them deal with questions like "how do I get a pointer to my data".


EDIT

I just made a primitive "box" macro:

#define box(value)                              \
({                                              \
    typeof(value) *ptr = malloc(sizeof *ptr);   \
    *ptr = value;                               \
    ptr;                                        \
})

Upvotes: 3

Related Questions