Quick actions

cmd+k|ctrl+k

Navigation

Languages

Stretchy Buffer

Snippet info

Language

Cpp

Visibility

public

Author

evine

Created

2018-03-16T18:38:31Z

Updated

2018-03-16T18:38:31Z

#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;
}
INFO