-
Notifications
You must be signed in to change notification settings - Fork 5
/
array.h
77 lines (60 loc) · 1.85 KB
/
array.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
#ifndef ARRAY_H
#define ARRAY_H
#include <string.h>
#include <stdlib.h>
struct _ArrayHeader {
size_t count, capacity;
};
#define ARRAY_INITIAL_SIZE 8
#define _arr_header(a) ((struct _ArrayHeader*)(a) - 1)
#define arr_init(a) arr_init_n((a), ARRAY_INITIAL_SIZE)
#define arr_init_n(a, n) do { \
struct _ArrayHeader *header; \
header = malloc(sizeof(*header) + (sizeof(*(a)) * (n))); \
header->count = 0; \
header->capacity = (n); \
(a) = (void*)(header + 1); \
} while(0)
#define arr_count(a) (_arr_header(a)->count)
#define arr_capacity(a) (_arr_header(a)->capacity)
#define arr_back(a) ((a)[arr_count(a) - 1])
#define arr_pop(a) ((a)[_arr_header(a)->count--])
#define arr_reserve(a, n) do { \
if(n <= arr_capacity(a)) break; \
struct _ArrayHeader *header = _arr_header(a); \
header->capacity = n; \
(a) = (void*)((struct _ArrayHeader*)realloc( \
header, sizeof(*header) + (sizeof(*(a)) * (n))) + 1); \
} while(0)
#define arr_resize(a, n) do { \
arr_reserve((a), (n)); \
_arr_header(a)->count = n; \
} while(0)
#define arr_resize_zero(a, n) do { \
size_t initial_count = arr_count(a); \
arr_resize((a), (n)); \
if(arr_count(a) > initial_count) \
memset( \
&(a)[initial_count], 0, \
(arr_count(a) - initial_count) * sizeof(*a)); \
} while(0)
// Take a vararg list to support compound literals
#define arr_add(a, ...) do { \
struct _ArrayHeader *header = _arr_header(a); \
if(header->count == header->capacity) \
arr_reserve((a), header->capacity << 1); \
(a)[_arr_header(a)->count++] = (__VA_ARGS__); \
} while(0)
#define arr_free(a) do { \
free(_arr_header(a)); \
} while(0)
#define arr_find(a, val, idx) do { \
*idx = -1; \
for(size_t i = 0; i < arr_count((a)); i++) { \
if((a)[i] == val) { \
*idx = i; \
break; \
} \
} \
} while(0)
#endif