0

I am trying to implement a generic and dynamic set data structure, yet I am struggling with the generic part. I understand that it is essentially an array of type pointer-to-void, but I just do not know how to enable the user to choose the type of the elements to add to a particular set. I have searched this site thoroughly, yet there does not seem to be an answer to my question. The dynamic_set type is defined as follows:

typedef struct
{
    int size;
    int capacity;
    void ** data;
} dynamic_set;

I need to know the type of the elements in order to be able to typecast the pointers and eventually dereference them so that I can check if the sets are compatible for a union, to decide on what type of function to apply to return an aggregate value, etc. Should I include another member in the above structure which represents the type of the elements within that set, like an enum? Any help is vastly appreciated!

  • 1
    If there is an operation that only the user (who knows the real type) can do, than require them to do it. Have the users supply callbacks that handle type specific actions (Like allocation, comparison, deallocation etc..). Same way as [qsort](http://en.cppreference.com/w/c/algorithm/qsort) handles it – StoryTeller - Unslander Monica Jul 06 '14 at 17:00
  • If you add an `enum`, you make a structure that can hold *every* type (that you care to enable). That's different from allowing *any* type (that you may not even know about). – Kerrek SB Jul 06 '14 at 17:04

1 Answers1

1

I can propose you to use pointers-to-functions to provide operations over the pointer stored values:

struct DynamicSet
{
    void** Items;
    size_t Size;
    size_t Capacity;
    int (*compare)(void*, void*);
};


DynamicSet* DynamicSet_Create(size_t capacity,
                              int (*compare)(void*, void*));

int CompareInts(void* left, void* right)
{
    int leftInt = *((int*)left);
    ...
}

DynamicSet* dynamicSet = DynamicSet_Create(100, CompareInts);

To use it with other type you just write another Comparator function.

But if you want more type safety and more convenient signatures for you functions you may try to emulate C++ templates with macro substitution.

Community
  • 1
  • 1
Eugene Podskal
  • 10,270
  • 5
  • 31
  • 53