Skip to content

Instantly share code, notes, and snippets.

@uniboi
Created December 21, 2023 13:20
Show Gist options
  • Save uniboi/04fd17843345b30630087276c5238e8f to your computer and use it in GitHub Desktop.
Save uniboi/04fd17843345b30630087276c5238e8f to your computer and use it in GitHub Desktop.
dynamic vector implementation
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
typedef int i32;
typedef unsigned int u32;
typedef long long i64;
typedef unsigned long long u64;
struct _DynamicVectorHead {
u32 cap;
u32 size;
char content[1];
};
#define vec(T) T*
#define vec_head(v) ((struct _DynamicVectorHead*)((u64)v - offsetof(struct _DynamicVectorHead, content)))
#define vec_content(vh) ((void*)vh->content)
#define vec_capacity(v) ((vec_head(v))->cap)
#define vec_size(v) ((vec_head(v))->size)
#define vec_new(T, size) ((T*)(_vec_new(sizeof(T), size)->content))
#define vec_free(v) free(vec_head(v))
#define vec_push(v, p) \
{ \
struct _DynamicVectorHead* vh = vec_head(v); \
if(vh->cap == vh->size) \
{ \
vh = _vec_resize(vh, sizeof(*v)); \
v = vec_content(vh); \
}\
v[vh->size] = p; \
vh->size++; \
}
#define vec_erase(v, i, n) _vec_erase(vec_head(v), i, n, sizeof(*v))
struct _DynamicVectorHead* _vec_new(u32 dsize, u32 size)
{
struct _DynamicVectorHead* v = malloc(sizeof(struct _DynamicVectorHead) + dsize * size - 1);
v->cap = size;
v->size = 0;
return v;
}
struct _DynamicVectorHead* _vec_resize(struct _DynamicVectorHead* v, u32 dsize)
{
struct _DynamicVectorHead* new = _vec_new(dsize, v->cap * 1.5);
new->size = v->size;
memmove(new->content, v->content, dsize * v->cap);
free(v);
return new;
}
void _vec_erase(struct _DynamicVectorHead* v, u32 idx, u32 n, u32 dsize)
{
memmove((void*)((u64)v->content + (idx * dsize)), (void*)((u64)(v->content) + (idx * dsize) + (n * dsize)), (v->size * dsize) - (idx * dsize) - (n * dsize));
v->size -= n;
}
int main()
{
struct Vector3 { i32 x, y, z; };
vec(struct Vector3) v = vec_new(struct Vector3, 4);
// create some dummy data
for(u32 i = 0; i < 20 * 3; i += 3)
vec_push(v, ((struct Vector3){ i, i + 1, i + 2}));
// erase the first two items
vec_erase(v, 0, 2);
// print the vec
for(u32 i = 0; i < vec_size(v); i++)
printf("[%2d] <%2d, %2d, %2d>\n", i, v[i].x, v[i].y, v[i].z);
// free the memory allocated for the vec
vec_free(v);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment