Vector 0.0.2
Loading...
Searching...
No Matches
polymorph.c
1#include "vector.h"
2
3#include <stdio.h>
4
5//
6// Add new types in that xmacro list:
7//
8#define TYPE_LIST \
9 X(cat) \
10 X(dog)
11
12typedef enum type
13{
14#define X(type) TYPE_##type,
15 TYPE_LIST
16#undef X
17 TYPE_LAST
18}
19type_t;
20
21// forward declaration of type specific data structures
22#define X(type) \
23 typedef struct type##_data type##_data_t;
24
25TYPE_LIST
26#undef X
27
28//
29// Add type specific functions declarations here:
30//
31#define X(type) \
32 void type##_create(void *const element, void *const param); \
33 int type##_make_sound(const void *const element, void *const param); \
34
35TYPE_LIST
36#undef X
37
38typedef struct object_header
39{
40 type_t type;
41 // extend header with variables,
42 // when shared data is required to store (a.k.a base class variables)
43
44 char data[]; // store type specific data in flexarr
45}
46object_header_t;
47
48//
49// Add type specific data structures:
50//
51typedef struct cat_data
52{
53 const char *favorite_fish;
54}
55cat_data_t;
56
57typedef struct dog_data
58{
59 const char *owners_name;
60}
61dog_data_t;
62
63// union used to calculate max allocation size that fit any type.
64union
65{
66#define X(type) type##_data_t type;
67 TYPE_LIST
68#undef X
69}
70data_t;
71
72typedef int (*make_sound_t) (const void *const element, void *const param);
73
74int make_sound(const void *const element, void *const param)
75{
76 // dynamic dispatch
77 static make_sound_t table[TYPE_LAST] = {
78#define X(type) type##_make_sound,
79TYPE_LIST
80#undef X
81};
82
83 const object_header_t* header = element;
84 return table[header->type](element, param);
85}
86
87
88void dog_create(void *const element, void *const param)
89{
90 object_header_t *object = element;
91 object->type = TYPE_dog;
92 dog_data_t *data = (dog_data_t*)&object->data;
93 *data = *(dog_data_t*)param;
94}
95
96
97void cat_create(void *const element, void *const param)
98{
99 object_header_t *object = element;
100 object->type = TYPE_cat;
101 cat_data_t *data = (cat_data_t*)&object->data;
102 *data = *(cat_data_t*)param;
103}
104
105
106int cat_make_sound(const void *const element, void *const param)
107{
108 (void) element;
109 (void) param;
110 printf("Meaw\n");
111 return 0;
112}
113
114
115int dog_make_sound(const void *const element, void *const param)
116{
117 (void) element;
118 (void) param;
119 printf("Woff\n");
120 return 0;
121}
122
123
124int main()
125{
126 const size_t size = 10;
127 vector_t *v = vector_create(.element_size = (sizeof(data_t) + sizeof(object_header_t)), .initial_cap = size);
128 for (size_t i = 0; i < size; ++i)
129 {
130
131 if (i % 2 == 0)
132 {
133 dog_create(vector_get(v, i), &(dog_data_t){.owners_name = "John"});
134 continue;
135 }
136
137 cat_create(vector_get(v, i), &(cat_data_t){.favorite_fish = "Salmon"});
138 }
139
140 (void) vector_foreach(v, size, make_sound, NULL);
142
143 return 0;
144}
void * vector_get(const vector_t *const vector, const size_t index)
Returns pointer for the element at index.
Definition vector.c:271
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.
Definition vector.c:382
#define vector_create(...)
Vector constructor.
Definition vector.h:162
void vector_destroy(vector_t *const vector)
Deallocates vector.
Definition vector.c:112
Vector control structure type.
Definition vector.c:24
Public interface of the vector.