-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvector.h
66 lines (53 loc) · 2.07 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
// https://gist.github.com/jaddison06/f9288ab0e138421cf38fcca12ac49a6c
#pragma once
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define _VecEntryName(name) _Vec_##name##_Entry
// doesn't do any additional typedefs so theoretically ur in the clear
// to have multiple identical vec types. probs best not to tho -
// keep this in .c files where poss
#define DECL_VEC(type, name) typedef struct name { \
type* root; \
int len, cap; \
type* elemTempStorage; \
} name; \
typedef type _VecEntryName(name);
#define DECL_VEC_NO_TYPEDEF(type, name) struct name { \
type* root; \
int len, cap; \
type* elemTempStorage; \
}; \
typedef type _VecEntryName(name);
#define INIT(vec) do { \
(vec).root = malloc(sizeof(*(vec).root)); \
(vec).cap = 1; \
(vec).len = 0; \
(vec).elemTempStorage = malloc(sizeof(*(vec).root)); \
} while(0)
#define DESTROY(vec) do { \
free((vec).root); \
free((vec).elemTempStorage); \
} while(0)
#define FOREACH(name, vec, iterator) for (_VecEntryName(name)* iterator = (vec).root; iterator - (vec).root < (vec).len; iterator++)
#define APPEND_ALL(name, to, from) FOREACH(name, from, current) APPEND(to, *current);
// new and improved! can take an rvalue - no need to pass in temporary variables!!
//
// when passing struct literals w/ multiple members put BRACKETS around them - i know
// what you mean but the precompiler doesn't :(
#define APPEND(vec, item) do { \
*(vec).elemTempStorage = (item); \
_append((void**)&((vec).root), (vec).elemTempStorage, sizeof(*(vec).elemTempStorage), &(vec).len, &(vec).cap); \
} while(0)
static void _append(void** vec, void* item, size_t size, int* currentLength, int* currentCapacity) {
if (*currentLength == *currentCapacity) {
*vec = realloc(*vec, *currentCapacity * size * 2);
*currentCapacity *= 2;
}
memcpy(&((*(char**)vec)[(*currentLength) * size]), item, size);
*currentLength += 1;
}
#define REMOVE(vec, idx) do { \
memcpy(&(vec).root[idx], &(vec).root[idx + 1], sizeof(*(vec).root) * ((vec).len - idx - 1)); \
(vec).len--; \
} while(0)