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
|
#pragma once
/**
*
* A collection of macros to create a doubly linked list of an arbitrary type.
*
* For normal usage just use LIST_AUTO(type, listTypeName) where type is the type to be stored and listTypeName is the desired typeName of the list container.
* List nodes get the type listTypeName##Entry.
*
* LIST_AUTO generates a list container struct of the name listTypeName,
* a list entry struct of the name listTypeName##Entry and
* functions of the name listTypeName##function for each function of
* New, Destroy, Empty (checks if the list is empty), Size, First, Last, Insert and Remove.
*
* For a simple foreach loop over a list use LIST_FOREACH(listTypeName, list, loopVariable),
* where listTypeName is the same as for LIST_AUTO, list is the list to be looped over and loopVariable is the name of the currently iterated list entry.
*
* (c) Markus Mittendrein - 2017-2018
*
**/
#include <stdbool.h>
#include <stdlib.h>
#define LIST_ENTRY_STRUCT(typeName, type) struct list_entry_##typeName {\
type value;\
struct list_entry_##typeName* next;\
struct list_entry_##typeName* prev;\
}
#define LIST_STRUCT(type) struct list_##type\
{\
struct list_entry_##type* head;\
struct list_entry_##type* tail;\
size_t size;\
}
#define LIST_NEW(type, name) struct list_##type* name(void)\
{\
struct list_##type* ret = malloc(sizeof(*ret));\
if(ret != NULL)\
{\
ret->head = NULL;\
ret->tail = NULL;\
ret->size = 0;\
}\
return ret;\
}
#define LIST_DESTROY(type, name) void name(struct list_##type* list)\
{\
for(struct list_entry_##type* entry = list->head; entry != NULL; )\
{\
struct list_entry_##type* tmp = entry;\
entry = entry->next; free(tmp);\
}\
free(list);\
}
#define LIST_EMPTY(type, name) bool name(struct list_##type* list) { return list->size == 0; }
#define LIST_SIZE(type, name) size_t name(struct list_##type* list) { return list->size; }
#define LIST_FIRST(type, name) struct list_entry_##type* name(struct list_##type* list) { return list->head; }
#define LIST_LAST(type, name) struct list_entry_##type* name(struct list_##type* list) { return list->tail; }
#define LIST_INSERT(typeName, type, name) struct list_entry_##typeName* name(struct list_##typeName* list, struct list_entry_##typeName* after, type value)\
{\
struct list_entry_##typeName* newEntry = malloc(sizeof(*newEntry));\
if(newEntry == NULL)\
{\
return NULL;\
}\
\
newEntry->value = value;\
newEntry->prev = after;\
\
if(after != NULL)\
{\
newEntry->next = after->next;\
after->next = newEntry;\
}\
else\
{\
newEntry->next = list->head;\
list->head = newEntry;\
}\
\
if(newEntry->next != NULL)\
{\
newEntry->next->prev = newEntry;\
}\
\
if(after == list->tail)\
{\
list->tail = newEntry;\
}\
\
++list->size;\
return newEntry;\
}
#define LIST_REMOVE(type, name) void name(struct list_##type* list, struct list_entry_##type* entry)\
{\
if(entry == list->head)\
{\
list->head = entry->next;\
}\
if(entry == list->tail)\
{\
list->tail = entry->prev;\
}\
\
if(entry->next != NULL)\
{\
entry->next->prev = entry->prev;\
}\
\
if(entry->prev != NULL)\
{\
entry->prev->next = entry->next;\
}\
\
free(entry);\
--list->size;\
}
#define LIST_AUTO(type, listTypeName) typedef LIST_ENTRY_STRUCT(listTypeName, type) listTypeName##Entry;\
typedef LIST_STRUCT(listTypeName) listTypeName;\
LIST_NEW(listTypeName, listTypeName##New)\
LIST_DESTROY(listTypeName, listTypeName##Destroy)\
LIST_EMPTY(listTypeName, listTypeName##Empty)\
LIST_SIZE(listTypeName, listTypeName##Size)\
LIST_FIRST(listTypeName, listTypeName##First)\
LIST_LAST(listTypeName, listTypeName##Last)\
LIST_INSERT(listTypeName, type, listTypeName##Insert)\
LIST_REMOVE(listTypeName, listTypeName##Remove)\
struct list_entry_##listTypeName* listTypeName##Append(struct list_##listTypeName* list, type value) { return listTypeName##Insert(list, list->tail, value); }\
struct list_entry_##listTypeName* listTypeName##Prepend(struct list_##listTypeName* list, type value) { return listTypeName##Insert(list, NULL, value); }
#define LIST_FOREACH(listTypeName, list, var) for(listTypeName##Entry* var = listTypeName##First(list); var != NULL; var = var->next)
|