-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlist_generic.h
213 lines (174 loc) · 6.96 KB
/
list_generic.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
#ifndef _LIST_GENERIC_
#define _LIST_GENERIC_
#include "list.h"
#include "foreach.h"
/* 1 */
#define LIST_TYPE(TYPE)\
typedef struct {list* _list;} list_##TYPE;
/* 2 */
#define LIST_METHOD_DECL_CREATE(TYPE)\
list_##TYPE* create_list_##TYPE();
#define LIST_METHOD_DECL_DESTROY(TYPE)\
void destroy_list_##TYPE(list_##TYPE* _list);
/* 3 */
#define LIST_METHOD_DEFN_CREATE(TYPE)\
list_##TYPE* create_list_##TYPE()\
{\
list_##TYPE* to_return = malloc(sizeof(list_##TYPE));\
if(!to_return) {\
fprintf(stderr, "\nERROR: memory allocation failed, list_%s* creation aborted.\n\n", #TYPE);\
to_return = NULL;\
} else {\
to_return->_list = create_list();\
}\
return to_return;\
}
#define LIST_METHOD_DEFN_DESTROY(TYPE)\
void destroy_list_##TYPE(list_##TYPE* _list)\
{\
destroy_list(_list->_list);\
free(_list);\
}
/* 4 */
#define LIST_METHOD_DECL_COUNT(TYPE)\
size_t list_##TYPE##_count(const list_##TYPE * _list);
#define LIST_METHOD_DECL_ADD(TYPE)\
size_t list_##TYPE##_add(list_##TYPE * _list, TYPE* _data);
#define LIST_METHOD_DECL_GET(TYPE)\
TYPE* list_##TYPE##_get(list_##TYPE * _list, size_t _index);
#define LIST_METHOD_DECL_SET(TYPE)\
bool list_##TYPE##_set(list_##TYPE * _list, size_t _index, TYPE* _data);
#define LIST_METHOD_DECL_INSERT(TYPE)\
bool list_##TYPE##_insert(list_##TYPE * _list, size_t _index, TYPE* _data);
#define LIST_METHOD_DECL_REMOVE(TYPE)\
bool list_##TYPE##_remove(list_##TYPE * _list, size_t _index);
/* 5 */
#define LIST_METHOD_DEFN_COUNT(TYPE)\
size_t list_##TYPE##_count(const list_##TYPE * _list)\
{\
return list_count(_list->_list);\
}
#define LIST_METHOD_DEFN_ADD(TYPE)\
size_t list_##TYPE##_add(list_##TYPE * _list, TYPE* _data)\
{\
_list->_list->count = list_add(_list->_list, _data);\
return _list->_list->count;\
}\
#define LIST_METHOD_DEFN_GET(TYPE)\
TYPE* list_##TYPE##_get(list_##TYPE * _list, size_t _index)\
{\
return list_get(_list->_list, _index);\
}\
#define LIST_METHOD_DEFN_SET(TYPE)\
bool list_##TYPE##_set(list_##TYPE * _list, size_t _index, TYPE* _data)\
{\
return list_set(_list->_list, _index, _data);\
}\
#define LIST_METHOD_DEFN_INSERT(TYPE)\
bool list_##TYPE##_insert(list_##TYPE * _list, size_t _index, TYPE* _data)\
{\
return list_insert(_list->_list, _index, _data);\
}\
#define LIST_METHOD_DEFN_REMOVE(TYPE)\
bool list_##TYPE##_remove(list_##TYPE * _list, size_t _index)\
{\
return list_remove(_list->_list, _index);\
}\
/* 6 */
#define LIST_METHOD_DECL_VAL_ADD(TYPE)\
size_t list_##TYPE##_add(list_##TYPE * _list, TYPE _value);
#define LIST_METHOD_DECL_VAL_GET(TYPE)\
TYPE list_##TYPE##_get(list_##TYPE * _list, size_t _index);
#define LIST_METHOD_DECL_VAL_GET_ADD(TYPE)\
TYPE* list_##TYPE##_get_address(list_##TYPE * _list, size_t _index);
#define LIST_METHOD_DECL_VAL_SET(TYPE)\
bool list_##TYPE##_set(list_##TYPE * _list, size_t _index, TYPE _value);
#define LIST_METHOD_DECL_VAL_INSERT(TYPE)\
bool list_##TYPE##_insert (list_##TYPE * _list, size_t _index, TYPE _value);
#define LIST_METHOD_DECL_VAL_REMOVE(TYPE)\
bool list_##TYPE##_remove (list_##TYPE * _list, size_t _index);
/* 8 */
#define LIST_METHOD_DECL_VAL_DESTROY(TYPE)\
void destroy_list_##TYPE(list_##TYPE* _list);\
/* 8 */
#define LIST_METHOD_DEFN_VAL_ADD(TYPE)\
size_t list_##TYPE##_add(list_##TYPE * _list, TYPE _value)\
{\
TYPE* temp = malloc(sizeof(TYPE));\
if(temp) *temp = _value;\
else return _list->_list->count;\
return list_add(_list->_list, temp);\
}\
#define LIST_METHOD_DEFN_VAL_GET(TYPE)\
TYPE list_##TYPE##_get(list_##TYPE * _list, size_t _index)\
{\
TYPE* temp = list_get(_list->_list, _index);\
return *temp;\
}\
#define LIST_METHOD_DEFN_VAL_GET_ADD(TYPE)\
TYPE* list_##TYPE##_get_address(list_##TYPE * _list, size_t _index)\
{\
TYPE* temp = list_get(_list->_list, _index);\
return temp;\
}\
#define LIST_METHOD_DEFN_VAL_SET(TYPE)\
bool list_##TYPE##_set(list_##TYPE * _list, size_t _index, TYPE _value)\
{\
list_node* node = list_get_node(_list->_list, _index);\
if(node) {\
*(TYPE *)node->data = _value;\
return true; }\
else\
return false;\
}\
#define LIST_METHOD_DEFN_VAL_INSERT(TYPE)\
bool list_##TYPE##_insert (list_##TYPE * _list, size_t _index, TYPE _value)\
{\
TYPE* temp = malloc(sizeof(TYPE));\
if(temp) *temp = _value;\
else return false;\
return list_insert(_list->_list, _index, temp);\
}\
#define LIST_METHOD_DEFN_VAL_REMOVE(TYPE)\
bool list_##TYPE##_remove (list_##TYPE * _list, size_t _index)\
{\
list_node* temp = list_get_node(_list->_list, _index);\
free(temp->data);\
return list_remove(_list->_list, _index);\
}\
/* 8 */
#define LIST_METHOD_DEFN_VAL_DESTROY(TYPE)\
void destroy_list_##TYPE(list_##TYPE* _list)\
{\
list_node* temp = _list->_list->begin;\
while(temp)\
{\
free(temp->data);\
temp = temp->next;\
}\
destroy_list(_list->_list);\
free(_list);\
}
/* 8 */
/* 7 */
#define LIST_DECLARE(TYPE)\
LIST_TYPE(TYPE) LIST_METHOD_DECL_CREATE(TYPE) LIST_METHOD_DECL_DESTROY(TYPE)\
LIST_METHOD_DECL_COUNT(TYPE) LIST_METHOD_DECL_ADD(TYPE) LIST_METHOD_DECL_GET(TYPE)\
LIST_METHOD_DECL_SET(TYPE) LIST_METHOD_DECL_INSERT(TYPE) LIST_METHOD_DECL_REMOVE(TYPE)\
#define LIST_DEFINE(TYPE)\
LIST_METHOD_DEFN_CREATE(TYPE) LIST_METHOD_DEFN_DESTROY(TYPE) LIST_METHOD_DEFN_COUNT(TYPE)\
LIST_METHOD_DEFN_ADD(TYPE) LIST_METHOD_DEFN_GET(TYPE) LIST_METHOD_DEFN_SET(TYPE)\
LIST_METHOD_DEFN_INSERT(TYPE) LIST_METHOD_DEFN_REMOVE(TYPE)\
#define LIST_VAL_DECLARE(TYPE)\
LIST_TYPE(TYPE) LIST_METHOD_DECL_CREATE(TYPE) LIST_METHOD_DECL_VAL_DESTROY(TYPE)\
LIST_METHOD_DECL_VAL_ADD(TYPE) LIST_METHOD_DECL_VAL_GET(TYPE) LIST_METHOD_DECL_VAL_GET_ADD(TYPE) LIST_METHOD_DECL_VAL_SET(TYPE)\
LIST_METHOD_DECL_VAL_INSERT(TYPE) LIST_METHOD_DECL_VAL_REMOVE(TYPE) LIST_METHOD_DECL_COUNT(TYPE)
#define LIST_VAL_DEFINE(TYPE)\
LIST_METHOD_DEFN_CREATE(TYPE) LIST_METHOD_DEFN_VAL_DESTROY(TYPE)\
LIST_METHOD_DEFN_VAL_ADD(TYPE) LIST_METHOD_DEFN_VAL_GET(TYPE) LIST_METHOD_DEFN_VAL_GET_ADD(TYPE) LIST_METHOD_DEFN_VAL_SET(TYPE)\
LIST_METHOD_DEFN_VAL_INSERT(TYPE) LIST_METHOD_DEFN_VAL_REMOVE(TYPE) LIST_METHOD_DEFN_COUNT(TYPE)
#endif
/* 8
To fix it, we need a custom destroy macro, LIST_METHOD_DEFN_VAL_DESTROY(TYPE) for LIST_VAL_DECLARE(TYPE) and LIST_VAL_DEFINE(TYPE).
This macro allow to clean all allocated memory when destroying the list, witch prevent leaks.
*/