#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <assert.h>
#include <string.h>
struct BufHdr{
size_t cap;
size_t len;
char buf[0];
};
BufHdr *buf__head(void *buf)
{
BufHdr *result = (BufHdr *)((char *)buf - sizeof(BufHdr));
return result;
}
void buf__push(void **buf, void *elem, size_t elem_size)
{
assert(buf != nullptr);
BufHdr *head;
if(*buf == nullptr)
{
head = (BufHdr *)malloc(sizeof(BufHdr) + elem_size);
head->cap = 1;
head->len = 0;
*buf = head->buf;
}
else
{
head = buf__head(*buf);
}
if(head->len + 1 > head->cap)
{
head->cap *= 2;
head = (BufHdr *)realloc(head, sizeof(BufHdr) + head->cap * elem_size);
*buf = head->buf;
}
memmove(head->buf + head->len * elem_size, elem, elem_size);
head->len += 1;
}
size_t buf__len(void *buf)
{
if(buf == nullptr) return 0;
BufHdr *header = buf__head(buf);
return header->len;
}
void buf__free(void *buf)
{
if(buf == nullptr) return;
BufHdr *header = buf__head(buf);
free(header);
}
template<typename T>
void buf_push(T **buf, T elem)
{
buf__push((void **)buf, &elem, sizeof(elem));
}
template<typename T>
size_t buf_len(T *buf)
{
return buf__len(buf);
}
template<typename T>
void buf_free(T *buf)
{
return buf__free(buf);
}
int main() {
int *b = nullptr;
buf_push(&b, 42);
buf_push(&b, 1234);
for(size_t i = 0; i < buf_len(b); ++i)
{
printf("%i\n", b[i]);
}
buf_free(b);
return 0;
}