#include <stdio.h>
#define TYPE_LIST \
X(cat) \
X(dog)
typedef enum type
{
#define X(type) TYPE_##type,
TYPE_LIST
#undef X
TYPE_LAST
}
type_t;
#define X(type) \
typedef struct type##_data type##_data_t;
TYPE_LIST
#undef X
#define X(type) \
void type##_create(void *const element, void *const param); \
int type##_make_sound(const void *const element, void *const param); \
TYPE_LIST
#undef X
typedef struct object_header
{
type_t type;
char data[];
}
object_header_t;
typedef struct cat_data
{
const char *favorite_fish;
}
cat_data_t;
typedef struct dog_data
{
const char *owners_name;
}
dog_data_t;
union
{
#define X(type) type##_data_t type;
TYPE_LIST
#undef X
}
data_t;
typedef int (*make_sound_t) (const void *const element, void *const param);
int make_sound(const void *const element, void *const param)
{
static make_sound_t table[TYPE_LAST] = {
#define X(type) type##_make_sound,
TYPE_LIST
#undef X
};
const object_header_t* header = element;
return table[header->
type](element, param);
}
void dog_create(void *const element, void *const param)
{
object_header_t *object = element;
object->type = TYPE_dog;
dog_data_t *data = (dog_data_t*)&object->
data;
*data = *(dog_data_t*)param;
}
void cat_create(void *const element, void *const param)
{
object_header_t *object = element;
object->type = TYPE_cat;
cat_data_t *data = (cat_data_t*)&object->data;
*data = *(cat_data_t*)param;
}
int cat_make_sound(const void *const element, void *const param)
{
(void) element;
(void) param;
printf("Meaw\n");
return 0;
}
int dog_make_sound(const void *const element, void *const param)
{
(void) element;
(void) param;
printf("Woff\n");
return 0;
}
int main()
{
const size_t size = 10;
vector_t *v =
vector_create(.element_size = (
sizeof(data_t) +
sizeof(object_header_t)), .initial_cap = size);
for (size_t i = 0; i < size; ++i)
{
if (i % 2 == 0)
{
dog_create(
vector_get(v, i), &(dog_data_t){.owners_name =
"John"});
continue;
}
cat_create(
vector_get(v, i), &(cat_data_t){.favorite_fish =
"Salmon"});
}
return 0;
}
void * vector_get(const vector_t *const vector, const size_t index)
Returns pointer for the element at index.
int vector_foreach(const vector_t *const vector, const size_t limit, const foreach_t func, void *const param)
Perform immutable action on each element of the vector.
#define vector_create(...)
Vector constructor.
void vector_destroy(vector_t *const vector)
Deallocates vector.
Vector control structure type.
Public interface of the vector.