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
|
// AMR ARRAY
// GENERAL ARRAYS FOR C
// > Mainly for prototyping and small internal programs
//
// Documentation:
//
// AMR_MALLOC:
// malloc function, can be replace with a custom allocator (todo)
// AMR_FREE:
// free function, can be replace with a custom allocator (todo)
// amr_arr_len:
// get array length
// amr_arr_cap:
// get array capacity
// amr_arr_init:
// initialize array, see usage for how to use.
// amr_arr_tinit:
// initialize array with type. gets around void cast issue, annoying on
// c++
// amr_arr_push(arr, value):
// push an element on to the end of an array.
// will not care about holes in array.
// amr_arr_pushcarr(arr, carr):
// push a c-style constant size array
// amr_arr_join(arr_a, arr_b):
// join/push all items from array b into array a
// amr_arr_clear(arr):
// clears array. (actually just resets the len variable of array,
// since operations first work on array len, this is all
// we need to "clear" it)
//
// Usage:
//
// typdef T arr_t; // optional, but recommended to signify a type is an array.
// // Highlights intent, prevents confusion
//
// int main() {
// arr_t *myarr;
// amr_arr_init(myarr, capacity);
//
// amr_arr_push(myarr, 2);
// ...
// }
#ifndef __AMR_INCLUDE_AMR_ARRAY_H
#define __AMR_INCLUDE_AMR_ARRAY_H
#include "stdlib.h"
#include "assert.h"
#include "string.h"
struct ArrayHeader {
int len;
int cap;
};
typedef struct ArrayHeader ArrayHeader;
#define __CARR_LEN(CARR) (sizeof((CARR))/sizeof((CARR)[0]))
#define AMR_MALLOC(x) malloc((x))
#define AMR_FREE(p) free((p))
#define amr_arr_len(A) ((((ArrayHeader*)(A)) - 1)->len)
#define amr_arr_cap(A) ((((ArrayHeader*)(A)) -1)->cap)
#define amr_arr_init(ARR, CAP) { \
ArrayHeader *H = (ArrayHeader*)AMR_MALLOC((CAP)*sizeof((ARR)[0]) + sizeof(ArrayHeader)); \
H->len = 0; \
H->cap = (CAP); \
ARR = (void*)(H+1); \
}
#define amr_arr_tinit(T, ARR, CAP) { \
ArrayHeader *H = (ArrayHeader*)AMR_MALLOC((CAP)*sizeof((ARR)[0]) + sizeof(ArrayHeader)); \
H->len = 0; \
H->cap = (CAP); \
ARR = (T*)(H+1); \
}
#define amr_arr_push(ARR, VAL) { \
ArrayHeader *H = ((ArrayHeader*)(ARR)-1); \
assert(H->len+1 <= H->cap); \
(ARR)[H->len++] = (VAL); \
}
#define amr_arr_pushcarr(ARR, ELE) { \
ArrayHeader *H = ((ArrayHeader*)(ARR)-1); \
assert(H->len+(__CARR_LEN((ELE))) <= H->cap); \
memcpy((ARR)+H->len, (ELE), sizeof((ELE))); \
H->len += (__CARR_LEN((ELE))); \
}
#define amr_arr_join(A, B) { \
ArrayHeader *HA = (ArrayHeader*)(A)-1; \
ArrayHeader *HB = (ArrayHeader*)(B)-1; \
assert(HA->len + HB->len <= HA->cap); \
memcpy((A) + HA->len, (B), sizeof((B)[0])*HB->len); \
HA->len += HB->len; \
}
#define amr_arr_clear(ARR) { \
ArrayHeader *H = (ArrayHeader*)(ARR)-1; \
H->len = 0; \
}
#define amr_arr_free(ARR) { \
AMR_FREE((ArrayHeader*)(ARR)-1); \
}
#endif // __AMR_INCLUDE_AMR_ARRAY_H
|