Skip to content

Instantly share code, notes, and snippets.

@LemoNode
Created February 16, 2022 23:17
Show Gist options
  • Save LemoNode/f5f54ae1426745da29c73beb35ef51e5 to your computer and use it in GitHub Desktop.
Save LemoNode/f5f54ae1426745da29c73beb35ef51e5 to your computer and use it in GitHub Desktop.
A simple array/buffer datastructure
#include <stdlib.h>
#include <stdint.h>
#include <assert.h>
// Dynamic Array:
// A stretchy buffer datastructure and a macro interface for both the buffers and static arrays.
// Structure idea by Sean Barrett:
// https://github.com/nothings/stb/blob/master/deprecated/stretchy_buffer.h
typedef struct BufHdr BufHdr;
typedef struct ArrHdr ArrHdr;
struct BufHdr {
size_t len;
size_t cap;
size_t size;
char buf[];
};
struct ArrHdr {
size_t len;
size_t cap;
char buf[];
};
struct BufHdr* bhdr (const void* buf) {
BufHdr* hdr = (BufHdr*)((char*)buf - offsetof(BufHdr, buf));
if (hdr->len == hdr->cap) {
hdr->cap <<= 1;
realloc(hdr, offsetof(BufHdr, buf) + hdr->size * hdr->cap);
}
return hdr;
}
void* buf_init (size_t size) {
size_t cap = 8;
BufHdr* hdr = malloc(offsetof(BufHdr, buf) + size * cap);
hdr->len = 0;
hdr->cap = cap;
hdr->size = size;
return hdr->buf;
}
void buf_free (const void* buf) {
free(bhdr(buf));
buf = 0;
}
// Buffer interface
#define bdel(b) buf_free(b)
#define bset(s) buf_init(s)
#define bcap(b) bhdr(b)->cap
#define blen(b) bhdr(b)->len
#define bput(b, ...) b[bhdr(b)->len++] = (__VA_ARGS__)
#define bclr(b) bhdr(b)->len = 0
// Array interface
#define ahdr(a) ((ArrHdr*)((char*)a - offsetof(ArrHdr, buf)))
#define aset(a, s) (char[(sizeof(*a)*s)+offsetof(ArrHdr, buf)]){0}; ahdr(a)->len = 0; ahdr(a)->cap = s
#define acap(a) ahdr(a)->cap
#define alen(a) ahdr(a)->len
#define aput(a, ...) a[ahdr(a)->len++] = (__VA_ARGS__)
#define aclr(a) ahdr(a)->len = 0
// Example
#if 0
int main (int argc, char** argv) {
// Buffer
{
int* b = bset(sizeof(int));
for (int i = 0; i < 10; i++) {
bput(b, i);
}
for (int i = 0; i < blen(b); i++) {
assert(b[i] == i);
}
bclr(b);
assert(blen(b) == 0);
bdel(b);
}
// Array
{
int* a = (int*)aset(a, 8);
for (int i = 0; i < acap(a); i++) {
aput(a, i);
}
for (int i = 0; i < acap(a); i++) {
assert(a[i] == i);
}
assert(alen(a) == acap(a));
aclr(a);
assert(alen(a) == 0);
}
return 0;
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment