-
Notifications
You must be signed in to change notification settings - Fork 2
/
vector.h
121 lines (104 loc) · 5.32 KB
/
vector.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
#ifndef _VECTOR_H
#define _VECTOR_H
#ifdef DURING_JIT
typedef unsigned long size_t;
typedef unsigned long uintptr_t;
void * malloc(size_t);
void * realloc(void *, size_t);
void free(void *);
#define assert(x)
#else
#include <stddef.h>
#include <assert.h>
#include <stdlib.h>
#endif
#define vector(type) type *
#define _internal_veccap(vec, size) \
do { \
if (vec) { \
((size_t *)(vec))[-1] = (size); \
} \
} while (0)
#define _internal_vecsiz(vec, size) \
do { \
if (vec) { \
((size_t *)(vec))[-2] = (size); \
} \
} while (0)
#define vector_capacity(vec) \
((vec) ? ((size_t *)(vec))[-1] : (size_t)0)
#define vector_size(vec) \
((vec) ? ((size_t *)(vec))[-2] : (size_t)0)
#define vector_empty(vec) \
(vector_size(vec) == 0)
#define vector_grow(vec, count) \
do { \
const size_t cv_sz = (count) * sizeof(*(vec)) + (sizeof(size_t) * 2); \
if (!(vec)) { \
size_t *cv_p = malloc(cv_sz); \
assert(cv_p); \
(vec) = (void *)(&cv_p[2]); \
_internal_veccap((vec), (count)); \
_internal_vecsiz((vec), 0); \
} else { \
size_t *cv_p1 = &((size_t *)(vec))[-2]; \
size_t *cv_p2 = realloc(cv_p1, (cv_sz)); \
assert(cv_p2); \
(vec) = (void *)(&cv_p2[2]); \
_internal_veccap((vec), (count)); \
} \
} while (0)
#define vector_pop_back(vec) \
do { \
_internal_vecsiz((vec), vector_size(vec) - 1); \
} while (0)
#define vector_erase(vec, i) \
do { \
if (vec) { \
const size_t cv_sz = vector_size(vec); \
if (((uintptr_t) (i)) < cv_sz) { \
_internal_vecsiz((vec), cv_sz - 1); \
size_t cv_x; \
for (cv_x = (i); cv_x < (cv_sz - 1); ++cv_x) { \
(vec)[cv_x] = (vec)[cv_x + 1]; \
} \
} \
} \
} while (0)
#define vector_free(vec) \
do { \
if (vec) { \
size_t *p1 = &((size_t *)(vec))[-2]; \
free(p1); \
} \
} while (0)
#define vector_insert(vec, idx, n) \
do { \
if(vec) { \
size_t cv_cap = vector_capacity(vec); \
if (cv_cap <= vector_size(vec)) { \
vector_grow((vec), cv_cap + 32); \
} \
for(size_t cv = vector_size(vec); cv > (uintptr_t) (idx); cv--) { \
(vec)[cv] = (vec)[cv - 1]; \
} \
(vec)[idx] = n; \
_internal_vecsiz((vec), vector_size(vec) + 1); \
} \
} while (0)
#define vector_begin(vec) \
(vec)
#define vector_end(vec) \
((vec) ? &((vec)[vector_size(vec)]) : NULL)
#define vector_foreach(type, name, vec) \
for(type * name = vector_begin(vec); name != vector_end(vec); ++name)
#define vector_push_back(vec, value) \
do { \
size_t cv_cap = vector_capacity(vec); \
if (cv_cap <= vector_size(vec)) { \
vector_grow((vec), cv_cap + 32); \
} \
vec[vector_size(vec)] = (value); \
_internal_vecsiz((vec), vector_size(vec) + 1); \
} while (0)
#endif