-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathds.h
133 lines (109 loc) · 2.75 KB
/
ds.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
122
123
124
125
126
127
128
129
130
131
132
133
#ifndef DS_H
#define DS_H
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <stdalign.h>
#include <assert.h>
#include <stdio.h>
typedef int8_t i8;
typedef uint8_t u8;
typedef int16_t i16;
typedef uint16_t u16;
typedef int32_t i32;
typedef uint32_t u32;
typedef int64_t i64;
typedef uint64_t u64;
typedef float f32;
typedef double f64;
typedef ptrdiff_t ssize;
#define arrlen(arr) (ssize) (sizeof(arr)/sizeof(arr[0]))
#define strify(c) #c
#define KiB (ssize) (1 << 10)
#define MiB (ssize) (1 << 20)
#define GiB (ssize) (1 << 30)
typedef struct {
u8 *buf;
ssize cap, len;
} Arena;
typedef struct {
u8 *buf;
ssize len;
} s8;
#define List(T) struct { T *buf; ssize len, cap; }
Arena new_arena(ssize cap);
#define new(a, T, c) ((a) ? arena_alloc(a, sizeof(T), _Alignof(T), c) : \
calloc(c, sizeof(T)))
void *arena_alloc(Arena *a, ssize size, ssize align, ssize count);
#define s8(lit) (s8){ .buf = (u8 *) lit, .len = arrlen(lit) - 1, }
s8 s8_copy(Arena *perm, s8 s);
void s8_modcat(Arena *perm, s8 *a, s8 b);
s8 s8_newcat(Arena *perm, s8 a, s8 b);
bool s8_equals(s8 a, s8 b);
void s8_print(s8 s);
u64 s8_hash(s8 s);
#endif // DS_H
#ifdef DS_IMPL
#ifndef DS_IMPL_GUARD
#define DS_IMPL_GUARD
Arena new_arena(ssize cap) {
return (Arena) { .buf = malloc(cap), .cap = cap, };
}
void *arena_alloc(Arena *a, ssize size, ssize align, ssize count) {
assert(align >= 0);
assert(size >= 0);
assert(count >= 0);
ssize pad = -(uintptr_t)(&a->buf[a->len]) & (align - 1);
ssize available = a->cap - a->len - pad;
assert(available >= 0);
assert(count <= available/size);
void *p = &a->buf[a->len] + pad;
a->len += pad + count * size;
return memset(p, 0, count * size);
}
s8 s8_copy(Arena *perm, s8 s) {
s8 copy = s;
copy.buf = new(perm, u8, copy.len);
memmove(copy.buf, s.buf, copy.len * sizeof(u8));
return copy;
}
void s8_modcat(Arena *perm, s8 *a, s8 b) {
assert(&a->buf[a->len] == &perm->buf[perm->len]);
s8_copy(perm, b);
a->len += b.len;
}
s8 s8_newcat(Arena *perm, s8 a, s8 b) {
s8 c = s8_copy(perm, a);
s8_modcat(perm, &c, b);
return c;
}
bool s8_equals(s8 a, s8 b) {
if (a.len != b.len) return false;
if (a.buf == NULL || b.buf == NULL) return false;
for (int i = 0; i < a.len; i++) {
if (a.buf[i] != b.buf[i]) return false;
}
return true;
}
void s8_print(s8 s) {
for (ssize i = 0; i < s.len; i++) {
printf("%c", s.buf[i]);
}
}
void s8_fprint(FILE *restrict stream, s8 s) {
for (ssize i = 0; i < s.len; i++) {
fprintf(stream, "%c", s.buf[i]);
}
}
u64 s8_hash(s8 s) {
u64 h = 0x100;
for (ssize i = 0; i < s.len; i++) {
h ^= s.buf[i];
h *= 1111111111111111111u;
}
return h;
}
#endif // DS_IMPL_GUARD
#endif // DS_IMPL