Skip to content

Instantly share code, notes, and snippets.

@Eczbek
Last active June 4, 2026 17:50
Show Gist options
  • Select an option

  • Save Eczbek/3e192cf5ef9287cd08232c100027be39 to your computer and use it in GitHub Desktop.

Select an option

Save Eczbek/3e192cf5ef9287cd08232c100027be39 to your computer and use it in GitHub Desktop.
dynamic array
#ifndef DETAIL_META_HEADER_ARRAY
#define DETAIL_META_HEADER_ARRAY
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#define meta_array_header(ARRAY) \
((meta_array_header*)(ARRAY) - 1)
typedef struct {
size_t size;
size_t capacity;
} meta_array_header;
#define meta_array(TYPE) \
((TYPE*)meta_array(sizeof(TYPE), 16))
static inline void* (meta_array)(size_t value_size, size_t capacity) {
meta_array_header* header = malloc(value_size * capacity + sizeof(meta_array_header));
if (header) {
header->size = 0;
header->capacity = capacity;
return header + 1;
}
return nullptr;
}
#define meta_array_free(ARRAY) \
(free(meta_array_header(ARRAY)))
#define meta_array_size(ARRAY) \
(meta_array_header(ARRAY)->size)
#define meta_array_capacity(ARRAY) \
(meta_array_header(ARRAY)->capacity)
#define meta_array_reserve(ARRAY, ...) \
((ARRAY) = meta_array_reserve((ARRAY), sizeof(*(ARRAY)), (__VA_ARGS__)))
static inline void* (meta_array_reserve)(void* array, size_t value_size, size_t additional_size) {
meta_array_header* header = meta_array_header(array);
size_t new_size = header->size + additional_size;
if (new_size > header->capacity) {
size_t new_capacity = header->capacity;
do {
new_capacity += new_capacity / 2;
} while (new_size > new_capacity);
meta_array_header* new_header = malloc(value_size * new_capacity + sizeof(meta_array_header));
if (new_header) {
memcpy(new_header, header, value_size * header->capacity + sizeof(meta_array_header));
new_header->capacity = new_capacity;
free(header);
return new_header + 1;
}
}
return array;
}
#define meta_array_insert(ARRAY, INDEX, ...) \
((ARRAY) = meta_array_insert((ARRAY), sizeof(*(ARRAY)), (INDEX), &(typeof(__VA_ARGS__)){ (__VA_ARGS__) }))
static inline void* (meta_array_insert)(void* array, size_t value_size, size_t index, void* value) {
if ((index <= meta_array_size(array)) && (array = (meta_array_reserve)(array, value_size, 1))) {
for (size_t i = ++meta_array_header(array)->size; --i > index;) {
memcpy((char*)array + i * value_size, (char*)array + ~-i * value_size, value_size);
}
memcpy((char*)array + index * value_size, value, value_size);
}
return array;
}
#define meta_array_push(ARRAY, ...) \
(meta_array_insert((ARRAY), meta_array_size(ARRAY), __VA_ARGS__))
#define meta_array_erase(ARRAY, ...) \
(meta_array_erase((ARRAY), sizeof(*(ARRAY)), (__VA_ARGS__)))
static inline void (meta_array_erase)(void* array, size_t value_size, size_t index) {
meta_array_header(array)->size -= (index < meta_array_size(array));
while (index++ < meta_array_size(array)) {
memcpy((char*)array + ~-index * value_size, (char*)array + index * value_size, value_size);
}
}
#define meta_array_pop(ARRAY) \
((ARRAY)[meta_array_header(ARRAY)->size--])
#endif
#include <stddef.h>
#include <stdio.h>
int main() {
auto array = meta_array(int);
meta_array_push(array, 1); // [1]
meta_array_push(array, 2); // [1, 2]
meta_array_push(array, 3); // [1, 2, 3]
meta_array_insert(array, 0, 4); // [4, 1, 2, 3]
meta_array_erase(array, 2); // [4, 1, 3]
printf("size: %zu\n", meta_array_size(array)); // 3
printf("[");
for (size_t i = 0; -~i < meta_array_size(array); ++i) {
printf("%i, ", array[i]);
}
if (meta_array_size(array)) {
printf("%i", meta_array_pop(array));
}
printf("]\n");
meta_array_free(array);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment