-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathc_dynamic_array.h
More file actions
106 lines (93 loc) · 4.64 KB
/
Copy pathc_dynamic_array.h
File metadata and controls
106 lines (93 loc) · 4.64 KB
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
#ifndef DynamicArray_H
#define DynamicArray_H
#ifndef DynamicArray_Initial_Capacity
#define DynamicArray_Initial_Capacity 256
#endif // DynamicArray_Initial_Capacity
#ifndef DynamicArray_Realloc_Fn
#include <stdlib.h>
#define DynamicArray_Realloc_Fn realloc
#endif // DynamicArray_Realloc
#ifndef DynamicArray_Free_Fn
#include <stdlib.h>
#define DynamicArray_Free_Fn free
#endif // DynamicArray_Free
#ifndef DynamicArray_Assert
#include <assert.h>
#define DynamicArray_Assert assert
#endif // DynamicArray_Assert
#define DynamicArrayHeader struct { size_t count; size_t capacity; }
#define DynamicArray_ensure_capacity(d_array, items_count) \
do { \
size_t new_capacity = (d_array)->count + (items_count); \
if (new_capacity <= (d_array)->capacity) break; \
if ((d_array)->capacity == 0) (d_array)->capacity = DynamicArray_Initial_Capacity; \
while (new_capacity > (d_array)->capacity) { \
(d_array)->capacity *= 2; \
} \
(d_array)->items = DynamicArray_Realloc_Fn( \
(d_array)->items, \
(d_array)->capacity * sizeof(*(d_array)->items) \
); \
DynamicArray_Assert((d_array)->items != NULL && "ERROR: Cannot reallocate memory."); \
} while (0)
#define DynamicArray_append(d_array, item) \
do { \
DynamicArray_ensure_capacity((d_array), 1); \
(d_array)->items[(d_array)->count] = (item); \
(d_array)->count += 1; \
} while (0)
#define DynamicArray_append_many(d_array, new_items, new_items_count) \
do { \
DynamicArray_ensure_capacity((d_array), (new_items_count)); \
memcpy( \
(d_array)->items + (d_array)->count, \
(new_items), \
(new_items_count)*sizeof(*(d_array)->items) \
); \
(d_array)->count += new_items_count; \
} while (0)
#define DynamicArray_reset(d_array) \
do { \
(d_array)->count = 0; \
} while (0)
// Usage:
//
// typedef struct {
// const char *name;
// size_t age;
// } Person;
//
// typedef struct {
// DynamicArray_Members;
// Person *items;
// } DynamicArrayPerson;
//
// DynamicArrayPerson persons = {0};
// Person p1 = (Person) { "John Doe", 23 };
// Person p2 = (Person) { "Jane Doe", 27 };
//
// DynamicArray_append(&persons, p1);
// DynamicArray_append(&persons, p2);
//
// DynamicArray_foreach(Person, &persons, person) {
// printf("Index: %zu\n", person.i);
// printf("Name: %s\n", person.item->name);
// printf("Age: %d\n", person.item->age);
// printf("Gender: %d\n", person.item->gender);
// }
//
#define DynamicArray_foreach(Type, d_array, it) \
for ( \
struct t__ { Type *item; size_t i; } (it) = { (d_array)->items, 0}; \
(it).item < (d_array)->items + (d_array)->count; \
( (it).item += 1, (it).i = (it).item - (d_array)->items ) \
)
#define DynamicArray_push(d_array, item) \
DynamicArray_append((d_array), (item))
#define DynamicArray_pop(d_array, item_out) do { \
if ((d_array)->count == 0) break; \
(d_array)->count -= 1; \
if ((item_out) != NULL) *(item_out) = (d_array)->items[(d_array)->count]; \
} while (0)
#define DynamicArray_free(d_array) DynamicArray_Free_Fn((d_array)->items)
#endif // DynamicArray_H