Created
December 21, 2023 13:20
-
-
Save uniboi/04fd17843345b30630087276c5238e8f to your computer and use it in GitHub Desktop.
dynamic vector implementation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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