views:

35

answers:

2

So i'm having trouble figuring how to overcome this.

Take for example, i have a red black tree implementation that works with items:

typedef unsigned long int Key;
struct rbt_node{
    Item item;
    int color;
    Key key;
    struct rbt_node* parent;
    struct rbt_node* left;
    struct rbt_node* right;
};

then in an Item.h i define the structure i'll be using, for example:

typedef struct _something* Item;

That way i'm decoupling the Item holded from the tree implementation. The problem arises if i want to reuse the ADT for other types.

At the moment i would have to define a Item2.h, and copy rbt.c/rbt.h to rbt2.c/rbt2.h and change them to use Item2.h and change the functions names. Isn't there any cleaner way?

I found this http://stackoverflow.com/questions/3274472/c-double-linked-list-with-abstract-data-type, but it seems to have some problems depending on the architecture and size of the structures, which i'm not really very knowledgeable.

I'm looking for this kind of usage:
rbt_insert(rbt_of_something, something);
rbt_insert(rbt_of_somethingElse, somethingElse);

Thanks

+3  A: 

You can put all your Items definitions in one single header file and use preprocessor to choose the right one:

#ifdef SOMETHING
typedef struct _something* Item;
#elif SOMETHINGELSE
typedef struct _somethingElse* Item;
#else
#error no definition for Item. Use -D flag to specify Item definition.
#endif

Then when compiling, just use -D arguments to define one of these macros.

Benoit Thiery
You probably want to use push/pop macros instead so you can use more than 1 type when compiling.
leppie
I don't see how that allows me to use the same rbt implementation for 2 different types of items in the same file. Could you elaborate?
GriffinHeart
@GriffinHeart: Use push/pop macros, or use `#undef` after including the header, and then define the next, and so on.
leppie
+2  A: 

Make the item member void*. Then define functions or macros that you use to assign/read the items to perform the required casts. e.g.

FILE* rbt_fileFromNode(struct rbt_node* node);

If you want to be really clever and you have a fixed number of types you'd like to put in there, add an enum to rbt_node or rbt_tree to store the type of the item.

JeremyP